VSI BASIC User Manual
- Software Version:
- VSI BASIC Version 1.8-4 for OpenVMS I64
VSI BASIC Version 1.8-5 for OpenVMS Alpha
- Operating System and Version:
- VSI OpenVMS Alpha Version 8.4-2L1 or higher
VSI OpenVMS IA-64 Version 8.4-1H1 or higher
Preface
Note
In this manual, the term OpenVMS refers to both OpenVMS I64 and OpenVMS Alpha systems. If there are differences in the behavior of the VSI BASIC compiler on the two operating systems, those differences are noted.
The term I64 BASIC refers to VSI BASIC on OpenVMS I64 systems.
Alpha BASIC refers to VSI BASIC on OpenVMS Alpha systems.
VAX BASIC refers to VAX BASIC on OpenVMS VAX systems.
1. About VSI
VMS Software, Inc. (VSI) is an independent software company licensed by Hewlett Packard Enterprise to develop and support the OpenVMS operating system.
2. Intended Audience
This manual is intended for programmers who compile, link, and execute VSI BASIC programs on OpenVMS systems. Users should have a working knowledge of BASIC or another high-level programming language, the Digital Command Language (DCL), and DCL command procedures.
3. Document Structure
This manual contains the following chapters and appendixes:
Part I, “Developing BASIC Programs on OpenVMS Systems”
Chapter 1, Overview of VSI BASIC provides a brief overview of VSI BASIC for OpenVMS.
Chapter 2, Developing VSI BASIC Programs describes how to develop programs at DCL command level and how to generate a compiler listing.
Chapter 3, Using the OpenVMS Debugger with BASIC describes how to use the OpenVMS Debugger to debug VSI BASIC for OpenVMS programs.
Part II, “BASIC Programming Concepts”
Chapter 4, BASIC Concepts and Elements explains how to get started with VSI BASIC for OpenVMS.
Chapter 5, Simple Input and Output explains simple input and output procedures.
Chapter 6, Arrays shows how to use arrays.
Chapter 7, Data Definition explains data definitions.
Chapter 8, Creating and Using Data Structures explains how to create user-defined data structures with the RECORD statement.
Chapter 9, Program Control shows how to control the flow of program execution.
Chapter 10, Functions explains how to use functions.
Chapter 11, String Handling explains how to handle strings.
Chapter 12, Program Segmentation describes structured programming techniques.
Chapter 13, File Input and Output explains how to manage files.
Chapter 14, Formatting Output with the PRINT USING Statement describes how to format output with the PRINT USING statement.
Chapter 15, Handling Run-Time Errors explains error-handling techniques.
Chapter 16, Compiler Directives shows how to use compiler directives.
Chapter 17, Data Representation describes how BASIC represents data.
Part III, “Using VSI BASIC for OpenVMS Features on OpenVMS Systems”
Chapter 18, Advanced File Input and Output describes additional I/O considerations on OpenVMS systems.
Chapter 19, Using BASIC in the Common Language Environment describes OpenVMS System Services and Run-Time Library routines.
Chapter 20, Libraries and Shareable Images describes the use of user-supplied libraries and shareable images.
Chapter 21, Using CDD/Repository with BASIC describes how to use CDD/Repository capabilities.
Chapter 22, Using DECwindows Motif Bindings with BASIC describes using standard Motif Bindings with BASIC.
Appendixes
Appendix A, Compile-Time Error Messages lists compile-time error messages.
Appendix B, Run-Time Messages lists run-time error messages.
Appendix C, Optional Programming Productivity Tools provides an overview of the optional productivity tools.
4. Related Documents
For more information about language elements, syntax, and reference information, see the VSI BASIC Reference Manual.
5. OpenVMS Documentation
The full VSI OpenVMS documentation set can be found on the VMS Software Documentation webpage at https://docs.vmssoftware.com.
6. VSI Encourages Your Comments
You may send comments or suggestions regarding this manual or any VSI document by sending electronic mail to the following Internet address: <docinfo@vmssoftware.com>
. Users who have VSI OpenVMS support contracts through VSI can contact <support@vmssoftware.com>
for help with this product.
7. Conventions
OpenVMS Industry Standard 64 for Integrity Servers
OpenVMS I64
I64
All three names—the longer form and the two abbreviated forms—refer to the version of the OpenVMS operating system that runs on the Intel ® Itanium ® architecture.
Convention |
Meaning |
---|---|
Ctrl/x |
A sequence such as Ctrl/x indicates that you must hold down the key labeled Ctrl while you press another key or a pointing device button. |
PF1 x |
A sequence such as PF1 x indicates that you must first press and release the key labeled PF1 and then press and release another key or a pointing device button. |
... |
A horizontal ellipsis in examples indicates one of the
following possibilities:
|
. . . |
A vertical ellipsis indicates the omission of items from a code example or command format; the items are omitted because they are not important to the topic being discussed. |
( ) |
In command format descriptions, parentheses indicate that you must enclose choices in parentheses if you specify more than one. |
[ ] | In command format descriptions, brackets indicate optional choices. You can choose one or more items or no items. Do not type the brackets on the command line. However,you must include the brackets in the syntax for OpenVMS directory specifications and for a substring specification in an assignment statement. |
| | In command format descriptions, vertical bars separate choices within brackets or braces. Within brackets, the choices are optional; within braces, at least one choice is required. Do not type the vertical bars on the command line. |
{ } |
In command format descriptions, braces indicate required choices; you must choose at least one of the items listed. Do not type the braces on the command line. |
bold type |
Bold type represents the name of an argument, an attribute, or a reason. |
italic type | Italic type indicates important information, complete titles of manuals, or variables. Variables include information that varies in system output (Internal error number), in command lines (/PRODUCER=name), and in command parameters in text (where dd represents the predefined code for the device type). |
UPPERCASE TYPE |
Uppercase type indicates a command, the name of a routine, the name of a file, or the abbreviation for a system privilege. |
- |
A hyphen at the end of a command format description, command line, or code line indicates that the command or statement continues on the following line. |
numbers |
All numbers in text are assumed to be decimal unless otherwise noted. Nondecimal radixes – binary, octal, or hexadecimal – are explicitly indicated. |
Part I. Developing BASIC Programs on OpenVMS Systems
Part I, “Developing BASIC Programs on OpenVMS Systems” provides an overview of BASIC and describes how to develop and debug BASIC programs. It shows you how to get started on the OpenVMS system and how to develop programs both at DCL command level and within the VAX BASIC Environment.
Chapter 1. Overview of VSI BASIC
BASIC is a powerful structured programming language designed for novice and application programmers alike.
BASIC was originally developed for students with little or no programming experience. Since then, BASIC has become one of the most widely used programming languages and is available on almost every computer system.
The OpenVMS implementations of BASIC have evolved beyond the original design but still support all of the traditional features of the original language in addition to more recent programming techniques. VSI BASIC has become much more than a teaching tool and is used in a wide variety of sophisticated applications.
1.1. Language Constructs Supported
Code without line numbers (traditional line numbers are optional)
Control structures, such as SELECT CASE
Explicit variable declarations
Capabilities for handling dynamic strings
Adaptable file-handling capabilities for terminal-format files, and the full range of RMS facilities
Global and local run-time error handling with WHEN ERROR blocks
Compile-time directives
A variety of data types, including packed-decimal, user-defined records, and VAX and IEEE floating-point data types.
Extensive error checking with meaningful error messages
Thirty-one character names for variables, labels, functions, and subprograms
1.2. Advantages on OpenVMS
The OpenVMS systems standard calling procedures
Record definitions included from the OpenVMS Common Data Dictionary
Code analysis with the Performance and Coverage Analyzer (PCA)
Creation of code with the Language-Sensitive Editor (LSE)
Extensive online language help
Exchange of data with other systems using DECnet
VSI BASIC supports features of other versions of BASIC, including PDP-11 BASIC-PLUS-2. The /FLAG qualifier allows you to check whether programs contain declining features that should be replaced with newer ones.
When you write programs in VSI BASIC, you develop programs at the DCL command level. You write your source program with a text editor, then compile, link, and run the program with commands to the OpenVMS operating system.
Chapter 2. Developing VSI BASIC Programs
This chapter describes how to compile, link, and run a VSI BASIC program.
For information about using a text editor to create and edit files, see the VSI OpenVMS User's Manual.
2.1. Compiling a VSI BASIC Program
Detects errors in your source program
Generates any appropriate error messages
Generates machine language instructions from the source statements
Groups these language instructions into an object module for the linker
To invoke the compiler, you use the DCL command BASIC. With the BASIC command, you can specify command qualifiers. The next sections discuss the BASIC command in detail as well as the command qualifiers available.
2.1.1. BASIC Command
BASIC [/qualifier...][ file-spec [/qualifier...]],...
/qualifier
Indicates a specific action to be performed by the compiler on all files or specific files listed. When a qualifier appears directly after the BASIC command, it affects all files listed.
file-spec
Indicates the name of the input source file that contains the program or module to be compiled. You are not required to specify a file extension; the VSI BASIC compiler assumes the default file type .BAS.
If the positional qualifier is located directly following the command name, it affects all the specified files.
If the file specifications are separated by commas, then any positional qualifier directly following a file specification affects only that file.
If the file specifications are separated by plus signs, then any positional qualifier directly following a list of file specifications affects only the resulting appended file.
The rightmost qualifier overrides any conflicting qualifier previously specified in the command line.
$
BASIC/LIST/OBJ PROG1/NOOBJ/DIAG,PROG2+PROG3/NOLIST
Compiles PROG1 and produces a listing file called PROG1.LIS
Produces no object file for PROG1
Produces a diagnostics file for PROG1 called PROG1.DIA
Appends PROG2 and PROG3 for compilation, producing a temporary source file called PROG2
Compiles the new PROG2 and produces an object file called PROG2.OBJ
Produces no listing file for the new PROG2
VSI BASIC does not require line numbers in either of the source files. The "+" operator is treated as an OpenVMS append operator. VSI BASIC appends and compiles the separate files as if they were a single source file.
2.1.2. BASIC Command Qualifiers
The following list shows the BASIC command qualifiers and their defaults. A description of each qualifier follows the list.
The qualifiers that are "declining features" and no longer recommended are separately described in Section 2.1.3, “Declining Qualifiers and Their Recommended Replacements”.
Command Qualifier |
Default |
---|---|
/[NO]ANALYSIS_DATA [ = file specification ] |
/NOANALYSIS_DATA |
/ARCHITECTURE = arch-type | /ARCHITECTURE = GENERIC |
/[NO]AUDIT [ = text-entry ] |
/NOAUDIT |
/[NO]CHECK [ = (check-clause,...) ] |
/CHECK=(BOUNDS,OVERFLOW) |
/[NO]CROSS_REF [ = [NO]KEYWORDS] |
/NOCROSS_REF |
/[NO]DEBUG [ = ( debug-clause,...) ] |
/DEBUG = (TRACEBACK,SYMBOLS) |
/DECIMAL_SIZE = (d,s) |
/DECIMAL_SIZE = (15,2) |
/[NO]DEPENDENCY_DATA |
/NODEPENDENCY_DATA |
/[NO]DIAGNOSTICS [ = file specification] |
/NODIAGNOSTICS |
/[NO]FLAG [ = ( flag-clause,... ) ] |
/FLAG = NODECLINING |
/INTEGER_SIZE = data-type |
/INTEGER_SIZE = LONG |
/[NO]LINES |
/LINES (VAX) /NOLINES (DEC) |
/[NO]LISTING [ = file specification ] |
/NOLISTING (from terminal) /LISTING (batch) |
/[NO]MACHINE_CODE |
/NOMACHINE_CODE |
/[NO]OBJECT [ = file-specification ] |
/OBJECT |
/[NO]OLD_VERSION [ = CDD_ARRAYS ] |
/NOOLD_VERSION |
/[NO]OPTIMIZE [ = LEVEL = n] |
/OPTIMIZE = LEVEL = 4 |
/REAL_SIZE = data-type |
/REAL_SIZE = SFLOAT (I64) or SINGLE (Alpha) |
/[NO]ROUND_DECIMAL |
/NOROUND_DECIMAL |
/SCALE = n |
/SCALE = 0 |
/[NO]SEPARATE_COMPILATION |
/NOSEPARATE_COMPILATION |
/[NO]SHOW [ = ( show-item,... ) ] |
/SHOW |
/[NO]SYNCHRONOUS_EXCEPTIONS |
/NOSYNCHRONOUS_EXCEPTIONS |
/TYPE_DEFAULT = default-clause |
/TYPE_DEFAULT = REAL |
/VARIANT = int-const |
/VARIANT = 0 |
/[NO]WARNINGS [ = ( warn-clause,...) ] |
/WARNINGS = (INFORMATIONALS, WARNINGS, NOALIGNMENT) |
- /[NO]ANALYSIS_DATA [ = file-specification ], /NOANALYSIS_DATA (default)
The /ANALYSIS_DATA qualifier generates a file containing data analysis information. This file has the file type .ANA. The Source Code Analyzer (SCA) library uses these files to display cross-reference information and to analyze source code.
Remarks
SCA must be installed.
- /ARCHITECTURE [ = {GENERIC | HOST | EV4 (Alpha only) | EV5 (Alpha only) | EV56 (Alpha only) | PCA56 (Alpha only) | EV6 (Alpha only) | EV67 (Alpha only) | ITANIUM2 (I64 only) | MERCED (I64 only)}], /ARCHITECTURE = GENERIC (default)
The /ARCHITECTURE qualifier specifies which version of the Itanium or Alpha architecture to generate instructions for.
All Itanium and Alpha processors implement a core set of instructions and, in some cases, the following extensions: BWX (byte- and word-manipulation instructions) and MAX (multimedia instructions).
OpenVMS Version 7.1 and subsequent releases include an instruction emulator. This capability allows any Itanium or Alpha chip to execute and produce correct results from Itanium or Alpha instructions, respectively, even if some of the instructions are not implemented on the chip. Applications using emulated instructions will run correctly, but might incur significant emulation overhead at run time.
Remarks
/ARCHITECTURE = GENERIC (default) generates instructions that are appropriate for all Itanium or Alpha processors.
/ARCHITECTURE = HOST generates instructions for the Itanium or Alpha processor that the compiler is running on (for example, EV56 instructions on an EV56 processor, and EV4 instructions on an EV4 processor).
/ARCHITECTURE = EV4 generates instructions for the EV4 processor (21064, 21064A, 21066, and 21068 Alpha chips).
Programs compiled with this option will not incur any emulation overhead on any Alpha processor.
/ARCHITECTURE = EV5 generates instructions for the EV5 processor (some 21164 Alpha chips).
Programs compiled with this option will not incur any emulation overhead on any Alpha processor.
/ARCHITECTURE = EV56 generates instructions for the EV56 processor (some 21164 Alpha chips). This option permits the compiler to generate any EV4 instruction, plus any instructions contained in the BWX extension.
Programs compiled with this option might incur emulation overhead on EV4 and EV5 processors.
Note that the EV5 and EV56 processor both have the same chip number: 21164.
/ARCHITECTURE = PCA56 generates instructions for the PCA56 processor (21164PC Alpha chip). This option permits the compiler to generate any EV4 instruction, plus any instructions contained in the BWX extension. Note that currently VSI BASIC does not generate any of the instructions in the MAX extension to the Alpha architecture.
Programs compiled with this option might incur emulation overhead on EV4 and EV5 processors.
/ARCHITECTURE = EV6 generates instructions for the EV6 processor (21264 Alpha chip). This option permits the compiler to generate any EV4 instruction, any instructions contained in the BWX and MAX extensions, plus any instructions added for the EV6 chip. These instructions include a floating-point square root instruction (SQRT), integer/floating-point register transfer instructions, and additional instructions to identify extensions and processor groups.
Programs compiled with this option might incur emulation overhead on EV4, EV5, EV56, and PCA56 processors.
/ARCHITECTURE = EV67 generates instructions for the EV67 processor (21264A Alpha chip). This option permits the compiler to generate any EV6 instruction, plus bit count instructions (CTLZ, CTPOP, and CTTZ). However, VSI BASIC does not generate any of the bit count instructions, so EV67 is essentially identical to EV6.
Programs compiled with this option might incur emulation overhead on EV4, EV5, EV56, and PCA56 processors.
/ARCHITECTURE = ITANIUM2 generates instructions for the Itanium 2 processor. This option permits the compiler to generate any Itanium 2 instructions.
/ARCHITECTURE = MERCED generates instructions for the Merced processor. This option permits the compiler to generate any Merced instructions.
- /[NO]AUDIT [ = {str-lit | file-specification}], /NOAUDIT (default)
- The /AUDIT qualifier causes the compiler to include a history entry in CDD/Repository when extracting a CDD/Repository definition. You can specify either a string literal or a file specification with the /AUDIT qualifier. If you specify a string literal, BASIC includes it as part of the history entry. If you specify a file specification, BASIC includes up to the first 64 lines of the specified file. When you specify /AUDIT, BASIC also includes the following information about the CDD/Repository record extraction in the history entry:
The name of the program module making the extraction
The time and date of the extraction
A note that access was made by way of a BASIC program
A note that the access was an extraction
The username and UIC of the process accessing CDD/Repository
Remarks
/NOAUDIT causes the compiler not to include a history entry in CDD/Repository when extracting a CDD/Repository definition.
- /[NO]CHECK [ = ({[NO]BOUNDS | [NO]OVERFLOW [NO]OVERFLOW [ = ([NO]INTEGER, [NO]DECIMAL)] | ALL | NONE}, ...) ], /CHECK = (BOUNDS,OVERFLOW) (default)
The /CHECK qualifier causes the compiler to test for arithmetic overflow and for array references outside array boundaries when the program executes.
Remarks
In Alpha BASIC, specifying /CHECK = NOBOUNDS causes bounds checking not to be performed on array parameters received by descriptor.
/CHECK = NOBOUNDS should only be used for thoroughly debugged programs and when execution time is critical. The program is smaller and runs faster, but no error is signaled for an array reference outside the array boundaries. The program might get a memory management or access violation error at run time.
/CHECK = OVERFLOW enables checking for integers and packed decimal numbers.
/CHECK = NOOVERFLOW disables overflow checking.
/NOCHECK causes the compiler not to test for arithmetic overflow or for array references outside array boundaries when the program executes.
/CHECK = ALL is the same as /CHECK = (BOUNDS, OVERFLOW).
/CHECK = NONE is the same as /NOCHECK.
- /[NO]CROSS_REFERENCE [ = [NO]KEYWORDS ], /NOCROSS_REFERENCE (default)
The /CROSS_REFERENCE qualifier causes the compiler to generate a cross-reference listing. The cross-reference list shows program symbols, classes, and the program lines in which they are referenced.
Remarks
/CROSS_REFERENCE = KEYWORDS specifies that the cross-reference listing includes all references to BASIC keywords. In Alpha BASIC, if the /LIST qualifier is not specified as well, /CROSS_REFERENCE is ignored.
The default for /CROSS_REFERENCE is NOKEYWORDS. See Chapter 16, Compiler Directives for more information about cross-reference listings.
/NOCROSS_REFERENCE specifies that no cross-reference listing be produced.
- /[NO]DEBUG [ = ( {[NO]SYMBOLS | [NO]TRACEBACK | ALL | NONE}, ...) ], /DEBUG = (TRACEBACK,SYMBOLS) (default)
The /DEBUG qualifier causes the compiler to provide information for the OpenVMS Debugger and the system run-time error traceback mechanism. Neither TRACEBACK nor SYMBOLS affects a program's executable code. For more information about debugging, see Chapter 3, Using the OpenVMS Debugger with BASIC.
Remarks
/NODEBUG causes the compiler to suppress information for the OpenVMS Debugger and the system run-time error traceback mechanism.
/DEBUG = ALL is the same as /DEBUG = (TRACEBACK,SYMBOLS).
/DEBUG = NONE is the same as /NODEBUG.
- /DECIMAL_SIZE = ( d,s ), /DECIMAL_SIZE = (15,2) (default)
The /DECIMAL_SIZE qualifier lets you specify the default size for packed decimal data. You specify the total number of digits in the number and the number of digits to the right of the decimal point.
/DECIMAL_SIZE = (15,2) is the default. This default decimal size applies to all decimal variables for which the total number of digits and digits to the right of the decimal point are not explicitly declared. See the VSI BASIC Reference Manual for more information about packed decimal numbers.
- /[NO]DEPENDENCY_DATA, /NODEPENDENCY_DATA (default)
The /DEPENDENCY_DATA qualifier generates a compiled module entity in the CDD$DEFAULT for each compilation unit.
Remarks
A compiled module entity is generated only if CDD/Plus Version 4.0 or higher or CDD/Repository Version 5.0 or higher is installed on your system and if your current CDD$DEFAULT is a CDO-format dictionary.
You must specify this qualifier if you want %INCLUDE %FROM %CDD and %REPORT %DEPENDENCY directives to establish dependency relationships.
/NODEPENDENCY_DATA causes the compiler not to generate a compiled module entity.
- /[NO]DIAGNOSTICS [ = file-spec ], /NODIAGNOSTICS (default)
The /DIAGNOSTICS qualifier creates a diagnostics file containing compiler messages and diagnostic information. The diagnostics file is used by LSE to display diagnostic error messages and to position the cursor on the line and column where a source error exists.
Remarks
The Language-Sensitive Editor (LSE) must be installed.
If you do not supply a file specification with the /DIAGNOSTICS qualifier, the diagnostics file has the same name as its corresponding source file and the file type .DIA. All other file specification attributes depend on the placement of the qualifier in the command. See the OpenVMS documentation set for more information.
/NODIAGNOSTICS specifies that no diagnostics file is created.
- /[NO]FLAG [ = {[NO]DECLINING | ALL | NONE}], /FLAG = NODECLINING (default)
The /FLAG qualifier lets you specify whether BASIC warns you about declining features.
Remarks
/NOFLAG causes the compiler to issue no warnings about declining features.
/FLAG = ALL is the same as /FLAG = DECLINING.
/FLAG = NONE is the same as /NOFLAG.
- /INTEGER_SIZE = {BYTE | WORD | LONG | QUAD}, /INTEGER_SIZE = (LONG) (default)
The /INTEGER_SIZE qualifier lets you specify the default size for integer data.
Remarks
The default integer size (LONG) applies to all integer variables whose data type is not explicitly declared. See the VSI BASIC Reference Manual for more information about integer data types.
- /[NO]LINES, /NOLINES (default)
The /LINES qualifier makes line number information available for the ERL function and the BASIC error reporter.
Remarks
- /NOLINES causes line number information to be unavailable for the ERL function and the VSI BASIC error reporter. Specifying /NOLINES makes your program run faster and reduces program size. However, specifying /NOLINES causes the following restrictions to be in effect:
You cannot use the ERL function.
No BASIC line number is given in run-time error messages.
- /[NO]LISTING [ = file-spec ], /LISTING (default in batch mode), /NOLISTING (default in interactive mode)
The /LISTING qualifier causes BASIC to produce a source listing file.
Remarks
/LISTING = file-spec produces a file with an explicit file specification. Omitting the file-spec produces a listing file with the same name as its corresponding source file and a file type of .LIS.
All other file specification attributes depend on the placement of the qualifier in the command. See the VSI OpenVMS User's Manual for more information.
/LISTING only controls whether or not the compiler produces a listing file and is the default in batch mode.
/SHOW controls which parts of the listing are produced.
/NOLISTING specifies that no source listing file be produced and is the default at a terminal.
- /[NO]MACHINE_CODE, /NOMACHINE_CODE (default)
The /MACHINE_CODE qualifier specifies that the listing file includes the compiler-generated object code.
Remarks
/MACHINE_CODE specifies that the compiler include a listing of the compiler-generated object code in the listing file. If the /LISTING qualifier is not specified as well, /MACHINE is ignored.
/NOMACHINE_CODE specifies that the listing file not include compiler-generated object code.
- /[NO]OBJECT [ = file-spec ], /OBJECT (default)
- The /OBJECT qualifier causes the compiler to produce an object module and optionally specifies its file name. By default, the compiler generates object files as follows:
If you specify one source file, BASIC generates one object file.
If you specify multiple source files separated by plus signs (+), BASIC appends the files and generates one object file.
If you specify multiple source files separated by commas (,), BASIC compiles and generates a separate object file for each source file.
You can use both plus signs and commas in the same command line to produce different combinations of appended and separated object files.
Remarks
/OBJECT = file-spec produces an object file with an explicit file specification. Omitting file-spec causes the compiler to produce an object file having the same name as its corresponding source file and the file type .OBJ. All other file specification attributes depend on the placement of the qualifier in the command. See the VSI OpenVMS User's Manual for more information.
/NOOBJECT suppresses the creation of an object file. During the early stages of program development, you might find it helpful to suppress the production of object files until your source program compiles without errors.
- /[NO]OLD_VERSION [ = CDD_ARRAYS], /NOOLD_VERSION (default)
The /OLD_VERSION qualifier causes the compiler to change the lower bound to zero and adjusts the upper bound of the array. For example, Array 2:5 in CDD/Repository is translated by the compiler to be an array with a lower bound of 0 and an upper bound of 3. The compiler issues an informational message to confirm the array bounds.
The /NOOLD_VERSION qualifier causes the compiler to extract an array from the CDD/Repository with the bounds as specified in the data definition. For example, Array 2:5 in CDD/Repository is translated by the compiler to be an array with a lower bound of 2 and an upper bound of 5.
Remarks
/OLD_VERSION [ = CDD_ARRAYS] is provided for compatibility with previous versions of BASIC.
CDD/Repository assumes a default lower bound of 1, if none is specified. Therefore, if no lower bound is specified, the compiler translates the CDD/Repository array to have a lower bound of 1. For example, Array 5 in CDD/Repository is translated by VSI BASIC to be an array with a lower bound of 1 and an upper bound of 5.
- /[NO]OPTIMIZE [ = {LEVEL [ = {0 | 1 | 2 | 3 | 4 (default)}] TUNE [ = {GENERIC (default) | HOST | EV4 | EV5 | EV56 | PCA56 | EV6 | EV67 | ITANIUM2 | MERCED }]}], /OPTIMIZE = LEVEL = 4 (default), /OPTIMIZE = TUNE = GENERIC (default)
The /OPTIMIZE qualifier causes the compiler to optimize the program to generate more efficient code for optimum run-time performance. Specifying /NOOPTIMIZE causes the compiler to perform minimal optimizations.
The following list describes the /OPTIMIZE = LEVEL options:0 has the same effect as /NOOPTIMIZE. Most optimizations are turned off.
1 has some optimizations (such as instruction scheduling).
2 adds more optimizations (such as loop unrolling and split lifetime analysis) to those in level 1.
3 adds more optimizations.
4 is the default level.
/OPTIMIZE = LEVEL = 4 is equivalent to /OPTIMIZE or not specifying the qualifier. Level 4 is the maximum optimization level.
The /OPTIMIZE = TUNE qualifier selects processor-specific instruction tuning for a specific implementation of the Itanium or Alpha architecture. Tuning for a specific implementation can provide improvements in run-time performance.
Regardless of the setting of the /OPTIMIZE = TUNE qualifier, the generated code will run correctly on all implementations of the Itanium or Alpha architecture as appropriate. Note that code tuned for a specific target might run more slowly on another target than generically-tuned code.
The following list describes the /OPTIMIZE = TUNE options:GENERIC (default) selects instruction tuning that is appropriate for all implementations of the Itanium or Alpha architecture.
HOST selects instruction tuning that is appropriate for the Itanium or Alpha machine on which the code is being compiled.
EV4 selects instruction tuning for the 21064, 21064A, 21066, and 21068 implementation of the Alpha architecture.
EV5 selects instruction tuning for the 21164 implementation of the Alpha architecture.
EV56 selects instruction tuning for the 21164 implementation of the Alpha architecture.
PCA56 selects instruction tuning for the 21164PC implementation of the Alpha architecture.
EV6 selects instruction tuning for the 21264 implementation of the Alpha architecture.
EV67 selects instruction tuning for the 21264A implementation of the Alpha architecture.
ITANIUM2 selects instruction tuning for the Itanium 2 implementation of the Itanium architecture.
MERCED selects instruction tuning for the Merced implementation of the Itanium architecture.
Remarks
Specify /NOOPTIMIZE if you specify /DEBUG when compiling a program. /NOOPTIMIZE expedites and simplifies the debugging session by putting the machine code in the same order as the lines in the source program. Optimizations can cause unexpected and confusing behavior in a debugging session.
Specifying /OPTIMIZE, the default, usually makes programs run faster. However, using /OPTIMIZE produces extra instructions to perform the optimization, which might result in larger object modules and longer compile times than the /NOOPTIMIZE qualifier.
To speed compilations during program development, compile with /NOOBJECT qualifier to check syntax, with /NOOPTIMIZE to check for correct execution, and finally with /OPTIMIZE for the final check.
- /REAL_SIZE = {SINGLE | DOUBLE | GFLOAT | SFLOAT | TFLOAT | XFLOAT}, /REAL_SIZE = SFLOAT (I64 default); SINGLE (Alpha default)
The /REAL_SIZE qualifier specifies the default size for floating-point data.
Remarks
The default floating-point size applies to all floating-point variables whose size is not explicitly declared.
See the VSI BASIC Reference Manual for more information about floating-point data types.
- /[NO]ROUND_DECIMAL, /NOROUND_DECIMAL (default)
The /ROUND_DECIMAL qualifier causes the compiler to round packed decimal numbers rather than truncate them.
The /NOROUND_DECIMAL qualifier causes the compiler to truncate packed decimal numbers rather than round them.
The /ROUND_DECIMAL qualifier causes the INTEGER function to round rather than truncate the decimal part.
- /SCALE = n, /SCALE = 0 (default)
The /SCALE qualifier specifies a scale factor from zero to six, inclusive. The scale factor affects only double-precision numbers. The SCALE qualifier helps to control accumulated round-off errors by multiplying floating-point values by 10 raised to the scale factor before storing them in variables. It is ignored for all but VAX double-precision (DOUBLE) floating-point numbers.
Remarks
The /SCALE qualifier is provided for compatibility with existing programs and with other implementations of BASIC. It is recommended that you do not use this feature for new program development. Accumulated round-off errors can be better controlled with packed decimal numbers. See the VSI BASIC Reference Manual for more information about packed decimal numbers.
- /[NO]SEPARATE_COMPILATION, /NOSEPARATE_COMPILATION (default)
The /SEPARATE_COMPILATION qualifier causes the compiler to place individual compilation units in separate modules in the object file. /NOSEPARATE_COMPILATION, the default, groups individual compilation units in a source file as a single module in the object file.
When creating modules for use in an object library, consider using /SEPARATE_COMPILATION to minimize the size of the routines included by the linker as it creates the executable image. /SEPARATE_COMPILATION also reduces the compiler virtual memory requirements when a source contains several compilation units.
Remarks
/SEPARATE_COMPILATION causes the compiler to place each routine in a separate module within the output object.
/NOSEPARATE_COMPILATION, in most cases, allows more interprocedural optimizations.
- /[NO]SHOW [ = ({[NO]CDD_DEFINITIONS |[NO]ENVIRONMENT | [NO]INCLUDE | [NO]MAP | [NO]OVERRIDE | ALL}, ... )], /SHOW = (CDD_DEFINITIONS, ENVIRONMENT, INCLUDE, MAP, NOOVERRIDE) (default)
The /SHOW qualifier determines which parts of the compilation listing are created.
Remarks
The size value for dynamically mapped arrays is the size of the actual array.
/LISTING must be specified for /SHOW to be effective.
CDD_DEFINITIONS controls whether the translation of a CDD/Repository record is displayed in the listing.
ENVIRONMENT lets you display all defaults that were in effect when the program was compiled. This is the compilation listing equivalent of the SHOW command in the environment.
INCLUDE controls whether files accessed with the %INCLUDE directive are displayed in the listing.
MAP determines whether the listing contains an allocation map. The allocation map lists all program variables, their size, and their data type.
OVERRIDE helps you debug code by disabling the effect of the %NOLIST directive.
/NOSHOW causes the compiler to display only the source listing.
/SHOW = ALL is the same as /SHOW = (CDD_DEFINITIONS, ENVIRONMENT, INCLUDE,MAP, OVERRIDE).
/SHOW = NONE is the same as /NOSHOW.
- /[NO]SYNCHRONOUS_EXCEPTIONS, /NOSYNCHRONOUS_EXCEPTIONS (default)
- The default /NOSYNCHRONOUS_EXCEPTIONS qualifier allows the compiler to reorder the execution of certain arithmetic instructions to improve performance on the hardware. If a program generates an arithmetic exception, such as an overflow or divide by zero, certain statements surrounding the offending statement may or may not be executed as a result of this reordering. Consider this example:
A = B C = D / E G = F
If the value of E is zero, the second statement will generate a divide by zero error. As a result of instruction reordering, it is possible that the assignment A = B will not take place. Further, it is possible that the assignment G = F will take place even though the previous statement generated an error.
The /SYNCHRONOUS_EXCEPTIONS qualifier disables reordering. Use this qualifier for programs that rely on arithmetic exceptions to occur at precise times during program execution.
The /SYNCHRONOUS_EXCEPTIONS qualifier impacts only arithmetic exceptions and variable assignments in the immediate area of the excepting statement.
Very few programs should require the /SYNCHRONOUS_EXCEPTIONS qualifier to produce correct results.
- /TYPE_DEFAULT = {INTEGER | REAL | DECIMAL | EXPLICIT}, /TYPE_DEFAULT = REAL (default)
The /TYPE_DEFAULT qualifier lets you specify the default data type for numeric variables.
Remarks
EXPLICIT specifies that all program variables must be explicitly declared in DECLARE, EXTERNAL, COMMON, MAP, or DIM statements.
INTEGER, REAL, or DECIMAL specify that only variables and data which are not explicitly declared default to integer, real, or packed decimal.
INTEGER_SIZE, REAL_SIZE, and DECIMAL_SIZE cause the compiler to specify the actual size of variables and data.
- /VARIANT = int-const
The /VARIANT qualifier lets you specify the value associated with the lexical function %VARIANT. See Chapter 16, Compiler Directives for more information about VARIANT and the %VARIANT lexical function.
Remarks
If /VARIANT is not specified, the default value is 0.
If /VARIANT is specified without a value, the default is 1.
- /[NO]WARNINGS [ = ({[NO]WARNINGS | [NO]INFORMATIONALS | [NO]ALIGNMENT | ALL NONE}, ... )], /WARNINGS = (INFORMATIONAL,WARNINGS,NOALIGNMENT) (default)
The /WARNINGS qualifier lets you specify whether BASIC displays informational and warning messages.
Remarks
/WARNINGS = NOWARNINGS causes the compiler to display informational messages but not warning messages.
/WARNINGS = NOINFORMATIONALS causes the compiler to display warning messages but not informational messages.
/NOWARNINGS causes the compiler to suppress any informational or warning messages.
/WARNINGS = ALIGNMENT causes the compiler to flag all occurrences of non-naturally aligned RECORD fields, variables within COMMONs and MAPs, and RECORD arrays.
An aligned data item starts on an address that is natural for that data type. Unaligned data accesses on Alpha can significantly reduce performance. Table 2.2, “Natural Boundaries For Supported Data Types” lists the natural boundaries for the supported data types.Table 2.2. Natural Boundaries For Supported Data Types Data Type
Natural Boundary
BYTE
BYTE
DECIMAL
BYTE
DOUBLE
QUADWORD
DYNAMIC STRING
BYTE
GFLOAT
QUADWORD
LONG
LONGWORD
QUAD
QUADWORD
RECORD
Depends on contents
RFA
BYTE
SFLOAT
LONGWORD
SINGLE
LONGWORD
STATIC STRING
BYTE
TFLOAT
QUADWORD
WORD
WORD
XFLOAT
OCTAWORD
/WARNINGS = NOALIGNMENT, the default, causes the compiler not to issue any warning messages about unaligned data.
The compiler naturally aligns all local variables and arrays, but it is the responsibility of the BASIC programmer to naturally align COMMONs, MAPS, and RECORDs. The /WARNINGS = ALIGNMENT qualifier flags all occurrences of non-naturally aligned items. This helps the programmer identify and correct unaligned entities.
An entity can be unaligned in the following ways:- The entity does not start on a natural boundary for its data type. There are several actions a programmer can take to resolve this:
Rearrange the RECORD, MAP, or COMMON so that all entities start on natural boundaries.
Force proper alignment with fill items, as needed.
Note that the natural alignment for a RECORD is equal to the largest alignment required by any of its fields. As an example, if a RECORD has a byte, long, and double field, the alignment of the RECORD would be quadword.
For arrays of RECORDs and GROUPs, items can be unaligned if the size of a RECORD or GROUP is not a multiple of the alignment requirements of that RECORD or GROUP. For example, if a RECORD has a natural alignment of quadword, the size of the RECORD must be a multiple of eight. Otherwise, all array elements after the first might start on an unaligned boundary. Avoid unaligned accesses by padding the end of the RECORD with fill items.
/WARNINGS = ALL is the same as /WARNINGS = (INFORMATIONAL, WARNINGS, ALIGNMENT).
/WARNINGS = NONE is the same as /NOWARNINGS.
2.1.3. Declining Qualifiers and Their Recommended Replacements
- /BYTE
- /DOUBLE
- /GFLOAT
- /LONG
- /SINGLE
- /TIE
- /WORD
Old Qualifier |
Recommended Replacement |
---|---|
/BYTE |
/INTEGER_SIZE = BYTE |
/DOUBLE |
/REAL_SIZE = DOUBLE |
/GFLOAT |
/REAL_SIZE = GFLOAT |
/LONG |
/INTEGER_SIZE = LONG |
/SINGLE |
/REAL_SIZE = SINGLE |
/TIE |
Move to using entirely native code |
/WORD |
/INTEGER_SIZE = WORD |
See the description of the /[NO]FLAG = [NO]DECLINING qualifier in this chapter. Also see the descriptions of the /INTEGER_SIZE and /REAL_SIZE qualifiers in this chapter. The old qualifiers are described in the VSI BASIC Reference Manual.
2.1.4. Compiler Listings
$
BASIC/LISTING prog-name
If the program is compiled as a batch job, the listing file is created by default; specify the /NOLISTING qualifier to suppress creation of the listing file. By default, the name of the listing file is the name of the source program followed by the file type .LIS. You can include a file specification with the /LISTING qualifier to override this default.
Source Program Listing
The source program section contains the source code and line numbers generated by the compiler.
Cross Reference
The cross reference section is present if the /CROSS_REFERENCE qualifier was specified. It contains cross references of variables, symbols, and so forth.
Allocation Map
The allocation map section contains summary information about program sections, variables, and arrays.
Qualifier Summary
The qualifier summary section lists the qualifiers used with the BASIC command and the compilation statistics.
Machine Code
The machine code section is present if the /MACHINE_CODE qualifier was specified. It contains a symbolic representation of the machine instructions generated for the program section.
2.2. Linking a VSI BASIC Program
On OpenVMS systems, the OpenVMS Linker (linker) simplifies the job of each language compiler because the logic needed to resolve symbolic references need not be duplicated. The main advantage to a system that has a linker, however, is that individual program modules can be separately written and compiled, and then linked together. This includes object modules produced by different language compilers.
Resolves local and global symbolic references in the object code
Assigns values to the global symbolic references
Signals an error message for any unresolved symbolic reference
Produces an executable image
When you link a program in development, in order to enable debugging, use the /DEBUG qualifier with the LINK command. The /DEBUG qualifier appends to the image all the symbol and line number information appended to the object modules plus information about global symbols, and forces the image to run under debugger control when you execute it (unless you then specify /NODEBUG).
The LINK command produces an executable image by default; however, you can also use the LINK command to obtain shareable images and system images. The /SHAREABLE qualifier directs the linker to produce a shareable image; the /SYSTEM qualifier directs the linker to produce a system image. See Section 2.2.2, “LINK Command Qualifiers” for a complete description of these and other LINK command qualifiers.
For a complete discussion of the OpenVMS Linker, see the VSI OpenVMS Linker Utility Manual.
2.2.1. LINK Command
LINK[ /command-qualifier]... {file-spec [/file-qualifier...]},...
/command-qualifier
Specifies one or more output file options.
file-spec
Specifies the input file or files to be linked.
/file-qualifier
Specifies one or more input file options.
If you specify more than one input file, you must separate the input file specifications with plus signs (+) or commas (,). By default, the linker creates an output file with the name of the first input file specified and the file type .EXE. When you link more than one file, list the file containing the main program first. This way, the name of your output file will have the same name as that of your main program module.
$
LINK DANCE.OBJ, CHACHA.OBJ, SWING.OBJ
2.2.2. LINK Command Qualifiers
The LINK command qualifiers can be used to modify linker output, as well as to invoke the debugging and traceback facilities. Linker output consists of an image file and an optional map file. Image file qualifiers, map file qualifiers, and debugging and traceback qualifiers are described in this section.
This section summarizes some of the most commonly used LINK command qualifiers. For a complete list and description of LINK qualifiers, see the VSI OpenVMS Linker Utility Manual.
- /BRIEF
The /BRIEF qualifier causes the linker to produce a summary of the image's characteristics and a list of contributing modules. This qualifier is used with /MAP.
- /[NO]CROSS_REFERENCE, /NOCROSS_REFERENCE (default)
The /CROSS_REFERENCE qualifier causes the linker to produce cross-reference information for global symbols; the /NOCROSS_REFERENCE qualifier causes the linker to suppress cross-reference information.
- /[NO]DEBUG, /NODEBUG (default)
The /DEBUG qualifier causes the linker to include the OpenVMS Debugger information in the executable image and generates a symbol table; the /NODEBUG qualifier causes the linker to prevent debugger control of the program. The default is /NODEBUG.
- /[NO]EXECUTABLE [= file-spec], /EXECUTABLE (default)
The /EXECUTABLE qualifier causes the linker to produce an executable image; the /NOEXECUTABLE qualifier suppresses production of an image file. If a file-spec is given, the resulting image is given the name of the file-spec.
- /FULL
The /FULL qualifier causes the linker to produce a summary of the image's characteristics, a list of contributing modules, listings of global symbols by name and by value, and a summary of characteristics of image sections in the linked image. This qualifier is used with /MAP.
- /[NO]MAP [= file-spec], /NOMAP (default interactive mode), /MAP (default batch mode)
The /MAP qualifier causes the linker to generate a map file; the /NOMAP qualifier suppresses the map. If a file-spec is given, the map file is given the name of the file-spec.
- /[NO]SHAREABLE, /NOSHAREABLE (default)
The /SHAREABLE qualifier causes the linker to create a shareable image; the /NOSHAREABLE qualifier generates an executable image.
- /[NO]TRACEBACK, /TRACEBACK (default)
The /TRACEBACK qualifier causes the linker to generate symbolic traceback information when error messages are produced; the /NOTRACEBACK qualifier suppresses traceback information.
2.2.3. Linker Input Files
Specify input file specifications for the object modules.
If no file type is specified, the linker assumes that an input file is an object file with the file type .OBJ.
Specify one or more object module library files.
You can either specify the name of an object module library with the /LIBRARY qualifier, or specify the names of object modules contained in an object module library with the /INCLUDE qualifier. The uses of object module libraries are described in Section 2.2.5, “Using an Object Module Library”.
Specify an options file.
An options file can contain additional file specifications for the LINK command as well as special linker options. You must use the /OPTIONS qualifier to specify an options file. For more information about options files, see the VSI OpenVMS Linker Utility Manual.
File |
File Type |
---|---|
Object module |
.OBJ |
Object library |
.OLB |
Options file |
.OPT |
2.2.4. Linker Output Files
When you enter the LINK command interactively and do not specify any qualifiers, the linker creates only an executable image file. By default, the resulting image file has the same file name as the first object module specified, and the file type .EXE.
In a batch job, the linker creates both an executable image file and a storage map file by default. The default file type for map files is .MAP.
$
LINK UPDATE/MAP=TEST
2.2.5. Using an Object Module Library
$
LINK GARDEN, VEGGIES/INCLUDE = (EGGPLANT,TOMATO,BROCCOLI,ONION)
This example directs the linker to link the object modules EGGPLANT, TOMATO, BROCCOLI, and ONION with the main object module GARDEN.
Besides program modules, an object module library can also contain a symbol table with the names of each global symbol in the library, and the name of the module in which they are defined. You specify the name of the object module library containing symbol definitions with the /LIBRARY qualifier. When you use the /LIBRARY qualifier during a link operation, the linker searches the specified library for all unresolved references found in the included modules during compilation.
$
LINK BADMINTON, TENNIS, RACQUETBALL, RACQUETS/LIBRARY
You can define an object module library, such as LNK$LIBRARY, to be your default library by using the DCL command DEFINE. The linker searches default user libraries for unresolved references after it searches modules and libraries specified in the LINK command. See the VSI OpenVMS DCL Dictionary for more information about the DEFINE command.
For more information about object module libraries, see the VSI OpenVMS Linker Utility Manual.
2.2.6. Linker Error Messages
If the linker detects any errors while linking object modules, it displays messages indicating the cause and severity of the error. If any error or fatal error conditions occur (errors with severities of E or F), the linker does not produce an image file.
An object module has compilation errors.
This error occurs when you attempt to link a module that has warnings or errors during compilation. You can usually link compiled modules for which the compiler generated messages, but you should verify that the modules will actually produce the output you expect.
The input file has a file type other than .OBJ and no file type was specified on the command line.
If you do not specify a file type, the linker assumes the file has a file type of .OBJ by default. If the file is not an object file and you do not identify it with the appropriate file type, the linker signals an error message and does not produce an image file.
You tried to link a nonexistent module.
The linker signals an error message if you misspell a module name on the command line or if the compilation contains fatal diagnostics.
A reference to a symbol name remains unresolved.
An error occurs when you omit required module or library names from the command line and the linker cannot locate the definition for a specified global symbol reference. For example, a main program module OCEAN.OBJ calls the subprograms located in object modules REEF.OBJ, SHELLS.OBJ, and SEAWEED.OBJ. However, the following LINK command does not reference the object module SEAWEED.OBJ:$
LINK OCEAN, REEF, SHELLS
This example produces the following error messages:%LINK-W-NUDFSYMS, 1 undefined symbol %LINK-I-UDFSYMS, SEAWEED %LINK-W-USEUNDEF, module "OCEAN" references undefined symbol "SEAWEED" %LINK-W-DIAGISUED, completed but with diagnostics
If an error occurs when you link modules, you can often correct the error by reentering the command string and specifying the correct modules or libraries.
See the OpenVMS System Messages and Recovery Procedures Reference Manual for a complete list of linker messages.
2.3. Running a VSI BASIC Program
RUN [/[NO]DEBUG] file-spec [/[NO]DEBUG]
/[NO]DEBUG
The /[NO]DEBUG qualifier is optional. Specify the /DEBUG qualifier to request the debugger if the image is not linked with it. You cannot use /DEBUG on images linked with the /NOTRACEBACK qualifier. If the image is linked with the /DEBUG qualifier, and you do not want the debugger to prompt, use the /NODEBUG qualifier. The default action depends on whether the file is linked with the /DEBUG qualifier.
file-spec
The name of the file you want to execute.
$
RUN SAMPLE/NODEBUG
See Chapter 3, Using the OpenVMS Debugger with BASIC for more information about debugging programs.
During program execution, an image can generate a fatal error called an exception condition. When an exception condition occurs, VSI BASIC displays an error message. Run-time errors can also be issued by other facilities, such as the OpenVMS operating system. For more information about run-time errors, see Appendix B, Run-Time Messages.
2.3.1. Improving Run-Time Performance of VSI BASIC Programs
Even with fast hardware and an optimizing compiler, you can still tune your code for run-time performance. This section provides recommendations to consider if further performance improvements are desirable.
To achieve the best performance for your application, it is important to let both the hardware and the optimizer/code generator take advantage of their full capabilities. This can be accomplished by minimizing, and in some cases avoiding, the use of language features and qualifiers that block optimal program execution.
2.3.1.1. Data Items
Align data items in MAP, COMMON, and RECORD statements. This is the recommended first step to improve performance. For more information on alignment, see Section 2.1.2, “BASIC Command Qualifiers” under /WARNING = ALIGNMENT.
Use LONG or QUAD data items instead of BYTE and WORD; accessing LONG or QUAD items is faster than BYTE and WORD, which may require multiple hardware instructions.
On Alpha, use GFLOAT or TFLOAT data items instead of DOUBLE; operations are faster on GFLOAT and TFLOAT items. Operations on DOUBLE operands are performed by converting to GFLOAT, performing the operation in GFLOAT, and converting back to DOUBLE.
On Itanium, use IEEE data items instead of VAX floating-point data items. VAX data type operands are converted to appropriate IEEE types before being operated on.
Choose packed decimal lengths that are the most efficient while still meeting the needs of the application. The most efficient sizes are the default size of 15 digits (which fits exactly in a quadword) and 7 digits (which fits exactly in a longword). If you use one of these preferred sizes, it should be aligned on a quadword or longword boundary.
Use packed decimal only when it is the appropriate data type. For example, do not use packed decimal to specify array subscripts, which are integers.
Minimize mixed data type expressions, especially when you use packed decimal.
2.3.1.2. Qualifiers
Use overflow and bounds checking only if they are needed. (See Section 2.1.2, “BASIC Command Qualifiers”; bounds checking is needed if your program is not thoroughly debugged.) Both of these /CHECK options are on by default and will hinder performance.
The use of the /LINES qualifier can impede optimization. /LINES is needed in Alpha BASIC only for the ERL function and to print BASIC line numbers in run-time error messages. /NOLINES is the default in Alpha BASIC.
The default optimization level, /OPTIMIZATION = LEVEL = 4, provides the highest level of optimization.
The /SYNCHRONOUS_EXCEPTIONS qualifier inhibits many optimizations. For more information on /SYNCHRONOUS_EXCEPTIONS, see Section 2.1.2, “BASIC Command Qualifiers”.
2.3.1.3. Statements
If you use error handling, the default ON ERROR GO BACK has the least impact on performance. ON ERROR GOTO {target} and WHEN blocks have a greater impact. If the application spends a large percentage of time in one routine, consider writing the routine with default error handling, if possible.
RESUME without a target impedes optimization. (This applies only to RESUME statements that do not specify a target.)
A MOVE TO or FIELD statement limits optimizations in the entire routine (SUB, FUNCTION, or main) where the statement is found. There is no additional cost for any statement after the first.
OPTION INACTIVE = SETUP can dramatically minimize routine startup times by omitting RTL calls that initialize and close down routines. For small BASIC routines, the overhead of these RTL calls can be significant. Use this option for routines that are frequently called.
If your routine contains any of the following elements, the compiler provides an informational diagnostic and emits calls to the RTL initialization and close-down routines:- CHANGE statements
- DEF statements
- Dynamic string variables
- Executable DIM statements
- EXTERNAL string functions
- MAT statements
- MOVE statements for an entire array
- ON ERROR statements
- READ statements
- REMAP statements
- RESUME statements
- WHEN blocks
- String concatenation
- Built-in string functions
- Virtual arrays
Routines using OPTION INACTIVE = SETUP cannot perform I/O and have no error-handling capabilities. If an error occurs in such a routine, the error is resignalled to the calling routine.
Using OPTION INACTIVE = SETUP instructs the compiler not to emit code to initialize local variables. This also improves run-time performance, but impacts routines that rely upon the automatic initialization of local variables.
CONTINUE without a target and RETRY can limit optimizations within the scope of the WHEN blocks associated with the handler that contains these statements. This impact can be significant if the handler is associated with a large WHEN block. The code within the associated WHEN blocks will be minimally optimized.
Chapter 3. Using the OpenVMS Debugger with BASIC
This chapter discusses OpenVMS Debugger information that is specific to the BASIC language. For more information about the OpenVMS Debugger, see the VSI OpenVMS Debugger Manual. Online help is available during debugging sessions.
3.1. Overview of the Debugger
A debugger is a tool to help you locate run-time errors quickly. It is used with a program that has already been compiled and linked successfully, with no errors reported, but that does not run correctly. For example, the output might be obviously wrong, the program goes into an infinite loop, or the program terminates prematurely. The debugger enables you to observe and manipulate the program's execution interactively, step by step, until you locate the point at which the program stopped working correctly.
The OpenVMS Debugger is a symbolic debugger, which means that you can refer to program locations by the symbols (names) you used for those locations in your program—the names of variables, routines, labels, and so on. You do not have to use virtual addresses to refer to memory locations.
The debugger recognizes the syntax, expressions, data typing, and other constructs of BASIC.
3.2. Compiling and Linking to Prepare for Debugging
$
BASIC/DEBUG INVENTORY
$
LINK/DEBUG INVENTORY
The /DEBUG qualifier with the BASIC command instructs the compiler to write the debug symbol records associated with INVENTORY into the object module, INVENTORY.OBJ. These records allow you to use the names of variables and other symbols declared in INVENTORY in debugger commands. (If your program has several compilation units, you must compile each unit that you want to debug with the /DEBUG qualifier).
The /DEBUG qualifier with the LINK command instructs the linker to include all symbol information that is contained in INVENTORY.OBJ in the executable image. The qualifier also causes the OpenVMS image activator to start the debugger at run time. (If your program has several object modules, you might need to specify other modules in the LINK command).
3.3. Viewing Your Source Code
The debugger provides two methods for viewing source code: noscreen mode and screen mode. By default when you invoke the debugger, you are in noscreen mode, but you might find that it is easier to view your source code with screen mode. Both modes are described in the following sections.
3.3.1. Noscreen Mode
Noscreen mode is the default, line-oriented mode of displaying input and output. To get into noscreen mode from screen mode, enter SET MODE NOSCREEN. See the sample debugging session in Section 3.7, “Sample Debugging Session” for a demonstration of noscreen mode.
DBG>
TYPE 3
3: EXTERNAL SUB TRIPLE &
DBG>
DBG>
TYPE TEST\16:21
3.3.2. Screen Mode
--SRC: module SAMPLE$MAIN -scroll-source-------------------------- 1: 10 !SAMPLE 2: 3: EXTERNAL SUB TRIPLE & 4: ,PRINT_SUB 5: 6: WHEN ERROR USE HANDLER_1 -> 7: CALL TRIPLE 8: CALL PRINT_SUB 9: - OUT -output--------------------------------------------- stepped to SAMPLE$MAIN\%LINE 7 - PROMPT -error-program-prompt---------------------------- DBG> STEP DBG>
Note
BASIC line numbers are treated as text by the debugger. In this chapter, line numbers refer to the sequential line numbers generated by the compiler. When a program includes or appends code from another file, the included lines of code are also numbered in sequence by the compiler. These line numbers are on the extreme left of a listing file. An explanation of the listing file format is in Chapter 2, Developing VSI BASIC Programs.
The PROMPT display, at the bottom of the screen, shows the debugger prompt (DBG>), your input, debugger diagnostic messages, and program output. In the example, the debugger commands that have been issued are shown.
The OUT display, in the center of the screen, captures the debugger's output in response to the commands that you issue.
The SRC and OUT displays are scrollable so that you can see whatever information scrolls beyond the display window's edge. Press KP8 to scroll up and KP2 to scroll down. Press KP3 to change the display to be scrolled (by default, the SRC display is scrolled). Scrolling a display does not affect program execution.
%DEBUG-I-SOURCESCOPE, Source lines not available for .0\%PC. Displaying source in a caller of the current routine.
The PC is within a system routine, or a shareable image routine for which no source code is available.
The PC is within a routine that was compiled without the /DEBUG compiler command qualifier (or with /NODEBUG).
The source file was moved to a different directory after it was compiled (the location of source files is embedded in the object modules). Use the SET SOURCE command to direct the debugger to the new location.
3.4. Controlling and Monitoring Program Execution
Starting and resuming program execution with the GO command
Stepping through the program's code with the STEP command
Determining the current location of the program counter (PC) with the SHOW CALLS command
Suspending program execution with breakpoints
Tracing program execution with tracepoints
Monitoring changes in variables with watchpoints
3.4.1. Starting and Resuming Program Execution
There are two commands for starting or resuming program execution: GO and STEP. The GO command starts execution. The STEP command lets you execute a specified number of source lines or instructions.
GO Command
The GO command starts program execution, which continues until forced to stop. You will probably use the GO command most often in conjunction with breakpoints, tracepoints, and watchpoints. If you set a breakpoint in the path of execution and then enter the GO command (or press the keypad comma key that executes the GO command), execution will be suspended when the program reaches that breakpoint. If you set a tracepoint, the path of execution through that tracepoint will be monitored. If you set a watchpoint, execution will be suspended when the value of the watched variable changes.
You can also use the GO command to test for an exception condition or an infinite loop. If an exception condition that is not handled by your program occurs, the debugger will take over and display the DBG> prompt so that you can issue commands. If you are using screen mode, the pointer in the source display will indicate where execution stopped. You can then use the SHOW CALLS command (see Section 3.4.2, “Determining the Current Location of the Program Counter”) to identify the currently active routine calls (the call stack).
In the case of an infinite loop, the program will not terminate, so the debugger prompt will not reappear. To obtain the prompt, interrupt the program by pressing Ctrl/Y and then issue the DCL command DEBUG. You can then look at the source display and a SHOW CALLS display to locate the PC.
STEP Command
The STEP command (which you can use either by entering STEP or by pressing KP0) allows you to execute a specified number of source lines or instructions, or to execute the program to the next instruction of a particular kind, for example, to the next CALL instruction.
DBG>
STEP
stepped to TEST\COUNTER\%LINE 27 27: X = X + 1DBG>
The PC is now at the first machine code instruction for line 27 of the module TEST; line 27 is in COUNTER, a routine within the module TEST. TEST\COUNTER\%LINE 27 is a directory specification. The debugger uses directory specifications to refer to symbols. (However, you do not need to use a path name in referring to a symbol, unless the symbol is not unique; in that case, the debugger will issue an error message). See the VSI OpenVMS Debugger Manual or online help for more information about resolving multiply-defined symbols.
DBG>
STEP 3
Note that only those source lines for which code instructions were generated by the compiler are recognized as executable lines by the debugger. The debugger skips over any other lines—for example, comment lines.
Also, if a line has more than one statement on it, the debugger will execute all the statements on that line as part of the single step.
Using the STEP/OVER command to step over a GOSUB statement will still proceed to the target of the GOSUB since this statement is just a special kind of GOTO statement and not a routine call.
You can specify different stepping modes, such as stepping by instruction rather than by line (SET STEP INSTRUCTION). To resume to the default behavior, enter the SET STEP LINE command. Also by default, the debugger steps over called routines—execution is not suspended within a called routine, although the routine is executed. By entering the SET STEP INTO command, you tell the debugger to suspend execution within called routines as well as within the currently executing module. To resume the default behavior, enter the SET STEP OVER command.
3.4.2. Determining the Current Location of the Program Counter
DBG>
SHOW CALLS
module name routine name line rel PC abs PC *TEST PRODUCT 18 00000009 0000063C *TEST COUNTER 47 00000009 00000647 *MY_PROG MY_PROG 21 0000000D 00000653
DBG>
Name of the module that contains the routine
Name of the routine
Line number at which the call was made (or at which execution is suspended, in the case of the current routine)
Corresponding PC addresses (the relative PC address from the start of the routine and the absolute PC address of the program)
This example indicates that execution is currently at line 18 of routine PRODUCT (in module TEST), which was called from line 47 of routine COUNTER (in module TEST), which was called from line 21 of routine MY_PROG (in module MY_PROG).
3.4.3. Suspending Program Execution
The SET BREAK command lets you select breakpoints, which are locations at which the program will stop running. When you reach a breakpoint, you can enter commands to check the call stack, examine the current values of variables, and so on.
DBG>
SET BREAK COUNTER
DBG>
GO
.
.
.
break at TEST\COUNTER 34: SUB COUNTER(LONG X,Y)DBG>
In this example, the SET BREAK command sets a breakpoint on the subprogram COUNTER; the GO command starts execution. When the subprogram COUNTER is encountered, execution is suspended, the debugger announces that the breakpoint at COUNTER has been reached (break at ...), displays the source line (34) where execution is suspended, and prompts you for another command. At this breakpoint, you can step through the subprogram COUNTER, using the STEP command, and use the EXAMINE command (see Section 3.5.1, “Displaying the Values of Variables”) to check on the current values of X and Y.
When using the SET BREAK command, you can specify program locations using various kinds of address expressions (for example, line numbers, routine names, instructions, virtual memory addresses). With high-level languages, you typically use routine names, labels, or line numbers, possibly with directory specifications to ensure uniqueness.
DBG>
SET BREAK %LINE 41
DBG>
SET BREAK SCREEN_IO\%LINE 58
DBG>
SET BREAK/LINE
DBG>
SET BREAK/CALL
DBG>
SET BREAK LOOP3 DO (EXAMINE TEMP)
DBG>
GO
.
.
. break at COUNTER\LOOP3 37: LOOP3: FOR I = 1 TO 10 COUNTER\TEMP: 284.19 DBG>
DBG>
SHOW BREAK
breakpoint at SCREEN_IO\%LINE 58 breakpoint at COUNTER\LOOP3 do (EXAMINE TEMP).
.
.
DBG>
To cancel a breakpoint, enter the CANCEL BREAK command, specifying the program location exactly as you did when setting the breakpoint. The CANCEL BREAK/ALL command cancels all breakpoints.
3.4.4. Tracing Program Execution
The SET TRACE command lets you select tracepoints, which are locations for tracing the execution of your program without stopping its execution. After setting a tracepoint, you can start execution with the GO command and then monitor the PC's path, checking for unexpected behavior. By setting a tracepoint on a routine, you can also monitor the number of times the routine is called.
DBG>
SET TRACE COUNTER
DBG>
GO
.
.
.
trace at TEST\COUNTER 34: SUB COUNTER(LONG X,Y).
.
.
When using the SET TRACE command, you specify address expressions, qualifiers, and optional clauses exactly as with the SET BREAK command.
DBG>
SET TRACE/LINE/NOSYSTEM/NOSHARE
DBG>
SET TRACE\SILENT %LINE 83 DO (EXAMINE STATUS)
DBG>
GO
.
.
.
SCREEN_IO\CLEAR\STATUS: 'OFF'.
.
.
3.4.5. Monitoring Changes in Variables
The SET WATCH command lets you set watchpoints that will be monitored continuously as your program executes.
DBG>
SET WATCH TOTAL
Subsequently, every time the program modifies the value of TOTAL, the watchpoint is triggered. The debugger monitors watchpoints continuously during program execution.
DBG>
SET WATCH TOTAL
DBG>
GO
.
.
.
watch of SCREEN_IO\TOTAL\%LINE 13 13: TOTAL = TOTAL + 1 old value: 16 new value: 17 break at SCREEN_IO.%LINE 14 14: CALL Pop_rtn(TOTAL) DBG>
In this example, a watchpoint is set on the variable TOTAL and the GO command starts execution. When the value of TOTAL changes, execution is suspended. The debugger announces the event (watch of …), identifying where TOTAL changed (line 13) and the associated source line. The debugger then displays the old and new values and announces that execution has been suspended at the start of the next line (14). (The debugger reports break at … , but this is not a breakpoint; it is still the effect of the watchpoint.) Finally, the debugger prompts for another command.
When a change in a variable occurs at a point other than the start of a source line, the debugger gives the line number plus the byte offset from the start of the line.
3.5. Examining and Manipulating Data
This section explains how to use the EXAMINE, DEPOSIT, and EVALUATE commands to display and modify the contents of variables, and evaluate expressions in BASIC programs.
3.5.1. Displaying the Values of Variables
DBG>
EXAMINE variable_name
The debugger recognizes the compiler-generated data type of the specified variable and retrieves and formats the data accordingly. The following examples show some uses of the EXAMINE command:
DBG>
EXAMINE EMPLOYEE_NAME
PAYROLL\EMPLOYEE_NAME: "Peter C. Lombardi"
DBG>
DBG>
EXAMINE WIDTH, LENGTH, AREA
SIZE\WIDTH: 4 SIZE\LENGTH: 7 SIZE\AREA: 28
DBG>
DBG>
EXAMINE INTEGER_ARRAY
PROG2\INTEGER_ARRAY (0,0): 27 (0,1): 31 (0,2): 12 (1,0): 15 (1,1): 22 (1,2): 18DBG>
DBG>
EXAMINE CHAR_ARRAY(4)
PROG2\CHAR_ARRAY(4): 'm'
DBG>
Note that the EXAMINE command can be used with any kind of address expression (not just a variable name) to display the contents of a program location. The debugger associates certain default data types with untyped locations. You can override the defaults for typed and untyped locations if you want the data to be interpreted and displayed in some other data format. The debugger supports the data types and operators of BASIC including RECORDs and RFAs.
See Section 3.5.3, “Evaluating Expressions” for an explanation of how the EXAMINE and the EVALUATE commands differ.
3.5.2. Changing the Values of Variables
DBG>
DEPOSIT variable_name = value
The DEPOSIT command is like an assignment statement in BASIC.
In the following examples, the DEPOSIT command assigns new values to different variables. The debugger checks that the value assigned, which may be a language expression, is consistent with the data type and dimensional constraints of the variable.
DBG>
DEPOSIT PARTNUMBER = "WG-7619.3-84"
DBG>
DEPOSIT WIDTH = CURRENT_WIDTH + 10
DBG>
DEPOSIT C_ARRAY(12) = 'K'
You can specify any kind of address expression, not just a variable name, with the DEPOSIT command (as with the EXAMINE command). You can override the defaults for typed and untyped locations if you want the data to be interpreted in some other data format.
3.5.3. Evaluating Expressions
DBG>
EVALUATE lang_exp
DBG>
DEPOSIT WIDTH = 45
DBG>
EVALUATE WIDTH + 7
52
DBG>
DBG>
DEPOSIT WIDTH = 45
DBG>
EVALUATE WIDTH
45
DBG>
EXAMINE WIDTH
SIZE\WIDTH: 45
DBG>
EVALUATE WIDTH + 7
52
DBG>
EXAMINE WIDTH + 7
SIZE\WIDTH: 131584
With the EVALUATE command, WIDTH + 7 is interpreted as a language expression, which evaluates to 45 + 7, or 52. With the EXAMINE command, WIDTH + 7 is interpreted as an address expression: 7 bytes are added to the address of WIDTH, and whatever value is in the resulting address is reported (in this example, 131584).
3.6. Stepping Into BASIC Routines
This section provides details of the STEP/INTO command that are specific to BASIC.
1 DECLARE LONG FUNCTION deffun (LONG) 2 DECLARE LONG A 3 DEF LONG deffun (LONG x) 4 deffun = x 5 END DEF . . . ->63 A = deffun (6%) 64 Print "The value of A is: "; A
The STEP/INTO command is useful for stepping into external functions and DEF functions in VSI BASIC for OpenVMS. If you use this command to step into GOSUB blocks, the debugger steps into Run-Time Library (RTL) routines, providing you with no useful information.
1 10 RANDOMIZE . . . ->8 GOSUB Print_routine 9 STOP . . . 20 Print_routine: 21 IF Competition = Done 22 THEN PRINT "The winning ticket is #";Winning_ticket 23 ELSE PRINT "The game goes on." 24 END IF 25 RETURN
As in the previous example, a STEP command alone will cause the debugger to proceed directly to source line 9.
Action |
Results |
---|---|
STEP/INTO DEF function |
Steps into function |
STEP/INTO DEF* function |
Steps into RTL |
STEP/INTO external function or SUB routine? |
Steps into function |
STEP/INTO GOSUB block |
Steps into RTL |
3.6.1. Controlling Symbol References
When using the OpenVMS Debugger, all VSI BASIC for OpenVMS variable and label names within a single program unit must be unique; otherwise, the debugger will be unable to determine the symbol to which you are referring.
3.7. Sample Debugging Session
This section shows a sample debugging session using a BASIC program that contains a logic error.
1 10 !SAMPLE program for DEBUG illustration 2 DECLARE INTEGER Number 3 Print_headers: 4 PRINT "NUMBER", "SQUARE", "SQUARE ROOT" 5 PRINT 6 Print_loop: 7 FOR Number = 10 TO 1 STEP -1 8 PRINT Number, Number^2, SQR(Number) 9 Number = Number + 1 10 NEXT Number 11 PRINT 12 END
$
BASIC/LIST/DEBUG SAMPLE
$
LINK/DEBUG SAMPLE
$
RUN SAMPLE
VAX DEBUG Version n.n
%DEBUG-I-INITIAL, language is BASIC module set to 'SAMPLE$MAIN'
DBG>
STEP 2
NUMBER SQUARE SQUARE ROOT
stepped to SAMPLE$MAIN\%line 7
7: FOR Number = 10 TO 1 STEP -1
DBG>
STEP 4
10 100 3.16228
stepped to SAMPLE$MAIN\%LINE 7
7: FOR Number = 10 TO 1 STEP -1
DBG>
EXAMINE Number
SAMPLE$MAIN\NUMBER: 10
DBG>
STEP 4
10 100 3.16228
stepped to SAMPLE$MAIN\%LINE 7
7: FOR Number = 10 TO 1 STEP -1
DBG>
EXAMINE Number
SAMPLE$MAIN\NUMBER: 10
DBG>
DEPOSIT Number = 9
DBG>
STEP 4
9 81 3
stepped to SAMPLE$MAIN\%LINE 7
7: FOR Number = 10 TO 1 STEP -1
DBG>
EXAMINE Number
SAMPLE$MAIN\NUMBER: 9
DBG>
STEP
9 81 3
stepped to SAMPLE$MAIN\%LINE 8
8: PRINT Number, Number^2, SQR(Number)
DBG>
STEP
stepped to SAMPLE$MAIN\%LINE 9
9: Number = Number + 1
DBG>
EXIT
Compile SAMPLE.BAS with the /LIST and /DEBUG qualifiers. The listing file can be useful while you are in the debugging session. | |
Link SAMPLE.BAS with the /DEBUG qualifier. | |
The debugger identifies itself and displays the debugger prompt after you invoke the debugger with the RUN command. | |
Step through 2 executable statements to the FOR statement. | |
The headers print successfully and the program reaches the FOR statement. | |
Step through one iteration of the loop. | |
Request the contents of the variable Number. | |
The debugger shows the contents of the loop index to be 10. | |
Step through another iteration of the loop. | |
Examine the value of the loop index again. | |
The debugger shows that the loop index is still 10. The loop index has not changed from its initial setting in the FOR statement. | |
Deposit the correct value into Number. | |
Step through another iteration of the loop. | |
Examine the contents of Number again. | |
Observe that the number has not been changed yet. | |
Step through just one statement to discover what is interfering with the value of Number during execution of the loop. | |
Observe that this statement does not affect the value of Number. | |
Step through another statement in the loop. | |
Observe that this statement counteracts the change in the loop index. | |
Exit from the debugger. You can now edit the program to delete line 9 and reprocess the program. Alternatively, you could use the EDIT command while in the debugger environment. |
This debugging session shows that the FOR...NEXT loop index ( Number) is not being changed correctly. An examination of the statements in the loop shows that the variable Number is being decreased by one during each execution of the FOR statement, but incremented by one with each execution of the loop statements. From this you can determine that the loop index will not change at all and the program will loop indefinitely. To correct the problem, you must delete the incorrect statement and recompile the source program.
3.8. Hints for Using the OpenVMS Debugger
A STEP at a statement that causes an exception might never return control to the debugger. The debugger cannot determine what statement in the BASIC source code will execute after the exception occurs. Therefore, set explicit breaks if STEP is used on statements that cause exceptions.
When you STEP at a statement that takes an error, the debugger will not regain control unless the program reaches an explicit breakpoint or the next statement that would have executed if no error had occurred. Set explicit breaks if you want the program to stop in any other place.
Use of the STEP command at a statement that takes an error does not return control to the debugger when the program reaches the error handler code. If you want the program to break when program execution enters an error handler, explicitly set a breakpoint at the error handler. This applies to both ON ERROR handlers and WHEN handlers.
If you are within a WHEN handler, a STEP at a statement that terminates execution within the WHEN handler (CONTINUE, RETRY, END WHEN, END HANDLER, EXIT HANDLER) will not stop unless program flow reaches a point where an explicit breakpoint is set.
STEP at a RESUME statement in an ON ERROR handler results in the program execution stopping at the first line of non-error-handler code.
Use SET BREAK/EXCEPTION at the beginning of the debugging session to prevent unexpected errors from occurring. This breakpoint is not necessary if you have set explicit breakpoints at all error handlers. However, use of this command will break at all exceptions, allowing you to check that you have the proper breakpoints to stop program execution following the exception.
Part II. BASIC Programming Concepts
Part II, “BASIC Programming Concepts” explains BASIC programming concepts including input and output, arrays, data definition, program control, and functions.
Chapter 4. BASIC Concepts and Elements
A BASIC program is a series of instructions for the compiler. These instructions are built using the fundamental elements of BASIC. This chapter describes these elements or building blocks.
4.1. Line Numbers
BASIC gives you the option of developing programs with line numbers or without line numbers.
4.1.1. Programs with Line Numbers
A line number must be a unique integer from 1 to 32767. VSI BASIC for OpenVMS does not allow programs to have duplicate line numbers.
A line number can contain leading zeros; however, embedded spaces, tabs, and commas are invalid in line numbers.
There must be a line number on the first line of the program.
If a source file contains subprograms, then each subprogram must begin on a numbered line.
In a multiple-unit program with line numbers, any comments following an END, END SUB, or END FUNCTION statement become a part of the previous subprogram during compilation unless they begin on a numbered line. This is not the case in multiple-unit programs without line numbers.
Although line numbers are not required, you might want to use them on every line that can cause a run-time error, depending on the type of error handling you use. See Chapter 15, Handling Run-Time Errors for more information about handling run-time errors.
4.1.2. Programs Without Line Numbers
Use a text editor to enter and edit the program.
No line numbers are allowed anywhere in the program module.
The ERL function is not allowed.
REM statements are not allowed.
In a multiple-unit program without line numbers, any comments following an END, END SUB, or END FUNCTION statement become a part of the next subprogram during compilation (unless there is no next subprogram). This is not the case in multiple-unit programs with line numbers.
You can avoid all of these restrictions by placing a line number on the first line of your program; no additional line numbers are required. The line number on the first program line causes the compiler to compile your program as a program with line numbers.
When you write a program with or without line numbers, you can begin your program statements in the first character position on a line.
!This is a short program that does not contain any !BASIC line numbers. !This program must be entered using a text editor; !it cannot be entered directly into the environment. ! PRINT "This program converts kilogram weight to pounds" INPUT "How many kilograms";A !This is the conversion factor B = A / 2.2 PRINT "For ";A;" kilograms, the pound weight is ";B END
Output
This program converts kilogram weight to pounds How many kilograms? 11 For 11 kilograms, the pound weight is 5
You can use exclamation comment fields instead of REM statements to insert comments into programs without line numbers. An exclamation point in column 1 causes the VSI BASIC compiler to ignore the rest of the line. You can also identify program statements in programs without line numbers by using labels.
4.1.3. Labels
A label is a 1- to 31-character identifier that you use to identify a block of statements. All label names must begin with a letter; the remaining characters, if any, can be any combination of letters, digits, dollar signs ($), underscores (_), or periods (.), but the final character cannot be a dollar sign.
Meaningful label names provide documentation.
You can use labels in programs with or without line numbers.
When you use a label to mark a program location, you must end the label with a colon (:). The colon is used to show that the label name is being defined instead of referenced. When you reference the label, do not include the colon.
OPTION TYPE = EXPLICIT ! Require declarations DECLARE INTEGER A . . . Outer_loop: IF A <> B THEN Inner_loop: IF B = C THEN A = A + 1 GOTO Outer_loop ELSE B = B + 1 GOTO Inner_loop END IF END IF
Labels have no effect on the order in which program lines are executed; they are used to identify a statement or block of statements.
4.1.4. Continuation of Long Program Statements
If a program line is too long for one line of text, you can continue the program line by placing an ampersand ( &) at the end of the line. Note that only spaces and tabs are valid between the ampersand and the carriage return.
OPEN "SAMPLE.DAT" AS FILE #2%, & SEQUENTIAL VARIABLE, & RECORDSIZE 80%
IF (A$ = B$) THEN PRINT "The two values are equal" ELSE PRINT "The two values are different" END IF
PRINT A \ PRINT V \ PRINT G
Because all statements are on the same program line, any reference to this program line refers to all three statements.
4.2. Identifying Program Units
PROGRAM Sort_out . . . END PROGRAM
If you include the PROGRAM statement in your program, the name you specify becomes the module name of the compiled source. This feature is useful when you use object libraries because the librarian stores modules by their module name rather than the file name. Similarly, module names are used by the OpenVMS Debugger and the OpenVMS Linker.
For more information about PROGRAM units, see Chapter 12, Program Segmentation.
4.3. BASIC Character Set
The letters A to Z, both uppercase and lowercase
The digits 0 to 9
Special characters
See the VSI BASIC Reference Manual for a complete list of the ASCII character set and character values.
The compiler does not distinguish between uppercase and lowercase letters, except for letters inside quotation marks (called string literals) or letters in a DATA statement. The compiler also does not process characters in a REM statement or comment field.
Use a predefined constant such as ESC or DEL
Use the CHR$ function to specify an ASCII value
See Section 4.6, “Constants” for more information about predefined constants. See Chapter 10, Functions for more information about the CHR$ function.
4.4. Program Documentation
Using meaningful variable names
Including sufficient white space
Indenting your program lines according to the structure of your code
PROGRAM sample !+ ! Require that all variables be declared !- OPTION TYPE = EXPLICIT !+ ! Set up error handler !- WHEN ERROR USE Error_routine !+ ! Declarations !- . . . END PROGRAM
DECLARE & INTEGER & Print_page, ! Current page number & Print_line, ! Current line number & Print_column ! Current column number
Note
Although you can also terminate a comment field with an exclamation point, this practice is not recommended. Any text that follows the second exclamation point is treated as part of your program code.
4.5. Declarations and Data Types
Implicit data typing
Explicit data typing
With implicit data typing, BASIC creates and specifies a data type for a variable the first time you reference it in your program. With explicit data typing, you must use one of four declarative statements (see Section 4.5.2, “Explicit Data Typing”) to name and type your program values.
Integer (INTEGER)
Floating-point (REAL)
String (STRING)
Packed Decimal (DECIMAL)
Record File Address (RFA)
The amount of storage required for the value; its container size
The range and precision that the value can accept
For more information about data types, see Chapter 8, Creating and Using Data Structures.
4.5.1. Implicit Data Typing
A percent sign suffix (%) specifies the INTEGER data type.
A dollar sign suffix ($) specifies the STRING data type.
Any other ending character specifies a variable of the default data type.
The default data type is SINGLE on Alpha BASIC and SFLOAT on I64 BASIC. However, you can specify your own default at DCL command level or with the OPTION statement in your program. For more information about establishing default data types, see Chapter 2, Developing VSI BASIC Programs, as well as the OPTION statement in the VSI BASIC Reference Manual.
The first time the variable is referenced, it creates a variable with that name and data type and allocates storage for that variable.
A% = 10.1 B% = 20.5 PRINT A% + B%
30
4.5.2. Explicit Data Typing
With explicit data typing, you use a declarative statement to name and specify a data type for your program values.
- DECLARE
- DIMENSION
- COMMON
- MAP
DECLARE and DIMENSION allocate dynamic storage for variables; storage is allocated when the program executes.
COMMON and MAP statements allocate storage for variables statically; storage is allocated when the program is compiled.
All declarative statements associate a data type with a variable. For more information, see Chapter 7, Data Definition.
4.6. Constants
Integer
Floating-point
Packed decimal
String
Formatting program output to improve clarity
Making source code easier to understand
Using nonprinting characters without having to look up their ASCII values
Constant |
Decimal ASCII Value |
Description |
---|---|---|
BEL (Bell) |
7 |
Sounds the terminal bell |
BS (Backspace) |
8 |
Moves cursor one position to the left |
HT (Horizontal Tab) |
9 |
Moves cursor to the next horizontal tab stop |
LF (Line Feed) |
10 |
Moves cursor to the next line |
VT (Vertical Tab) |
11 |
Moves cursor to the next vertical tab stop |
FF (Form Feed) |
12 |
Moves cursor to the start of the next page |
CR (Carriage Return) |
13 |
Moves cursor to the beginning of the current line |
SO (Shift Out) |
14 |
Shifts out for communications networking, screen formatting, and alternate graphics |
SI (Shift In) |
15 |
Shifts in for communications networking, screen formatting, and alternate graphics |
ESC (Escape) |
27 |
Marks the beginning of an escape sequence |
SP (Space) |
32 |
Inserts one blank space in program output |
DEL (Delete) |
127 |
Deletes the last character entered |
PI |
None |
Represents the number PI with the precision of the default floating-point data type |
PRINT BEL
You can also create your own predefined constants with the DECLARE CONSTANT statement.
For more information about constants, see Chapter 7, Data Definition and the VSI BASIC Reference Manual.
4.7. Variables
A variable is a storage location that is referred to by a variable name. Variable values can change during program execution. Each named location can hold only one value at a time.
A variable name can have up to 31 characters. The name must begin with a letter; the remaining characters, if any, can be any combination of letters, digits, dollar signs ($), underscores (_), and periods (.).
Variables can be grouped in an orderly series (such as a list or table) under a single name, called an array. You refer to a single variable in an array by using one or more subscripts that specify the variable's position in the array. (See Section 4.7.5, “Subscripted Variables” for more information on arrays).
4.7.1. Floating-Point Variables
A floating-point variable is a named location that stores a floating-point value. The storage space required to hold the value depends on the variable's REAL subtype. For example, each SINGLE floating-point variable requires 32 bits (4 bytes) of storage, while each DOUBLE floating-point variable requires 64 bits (8 bytes) of storage.
Note that if any integer value is assigned to a floating-point variable, the value is converted to a floating-point number.
4.7.2. Integer Variables
An integer variable is a named location that stores a whole number. The storage space required to hold the value depends on the variable's INTEGER subtype. For example, each BYTE integer variable requires 8 bits (1 byte) of storage, while each LONG integer variable requires 32 bits (4 bytes) of storage.
B% = -5.7
DECLARE WORD CONSTANT Word_const = -32767 - 1
4.7.3. Packed Decimal Variables
A packed decimal (DECIMAL data type) variable is made up of several storage locations, the number of which depends on the declared size of the variable. However, a packed decimal variable is still referred to by a single variable name.
When you declare a packed decimal variable, you specify the total number of digits and the number of digits to the right of the decimal place that you want.
OPTION TYPE = EXPLICIT DECLARE DECIMAL (8,2) My_decimal
Packed decimal numbers are most useful for dollars-and-cents calculations.
4.7.4. String Variables
DECLARE STRING Employee_name
4.7.5. Subscripted Variables
A subscripted variable is a floating-point, integer, packed decimal, RFA, or string variable that is part of an array. Chapter 6, Arrays describes arrays in more detail.
An array is a set of data organized in one or more dimensions. A one-dimensional array is called a list or vector. A two-dimensional array is called a matrix. Arrays can have up to 32 dimensions.
When you create an array, its size is determined by the number of dimensions and the maximum size, called the bound, of each dimension. Subscripts begin by default with 0, not 1. That is, when calculating the number of elements in a dimension, you count from zero to the bound specified.
DECLARE INTEGER My_array (10, 10)
OPTION TYPE = EXPLICIT, & SIZE = REAL SINGLE DECLARE REAL Birth_rates(1945 TO 1985)
Note
By default, the compiler signals an error if a subscript is larger than the allowable range. Also, the amount of storage that the system can allocate depends on available memory. Therefore, very large arrays can cause an internal allocation error.
4.7.6. Initialization of Variables
Numeric variables and array elements (except those in MAP or COMMON statements).
String variables and array elements (except those in MAP or COMMON statements).
Variables in subprograms. Subprogram variables (except those in MAP or COMMON statements) are initialized to zero or the null string each time the subprogram is called.
Arrays created with an executable DIMENSION statement. The array is reinitialized each time the array is redimensioned.
4.8. Keywords and Reserved Words
Define data
Perform operations
Invoke functions
See the VSI BASIC Reference Manual for a list of keywords and reserved words.
Keywords determine whether the statement is executable or nonexecutable. Executable statements such as PRINT, GOTO, and READ perform operations. Nonexecutable statements such as DATA, DECLARE, and REM describe the characteristics and arrangement of data, usage information, and comments.
Every statement except LET must begin with a keyword. A keyword cannot have embedded spaces or be split across lines of text. There must be a space or tab between the keyword and any other variables or operators.
There are also phrases of keywords. In this case, the spacing requirements vary.
4.9. Operands, Operators, and Expressions
An operand contains a value. An operand can be a scalar, subscripted variable, named constant, literal, and so on. An operator specifies a procedure to be carried out by one or more operands. An expression consists of operands separated by operators.
- Arithmetic
- String
- Relational
- Logical
Numeric expressions
String expressions
Conditional expressions
For more information about operands, operators, and expressions, see the VSI BASIC Reference Manual.
4.10. Assignment Statements
LET
INPUT
LINPUT
INPUT LINE
LET A = 1.25
LET is an optional keyword. You can assign a value to more than one variable at a time, although this is not recommended. Instead, use a separate assignment statement each time you assign a value to a variable.
Whenever you assign a value to a numeric variable, BASIC converts the value to the data type of the variable. If you assign a floating-point value to an integer variable, BASIC truncates the value at the decimal point. If you assign an integer value to a floating-point variable, BASIC converts the value to floating-point format.
You can also assign values to variables with the DATA and READ statements; however, this method requires that you know all input data values while you are coding your program.
The INPUT, LINPUT, and INPUT LINE statements all assign values in the context of data being read into the program. These statements are discussed in Chapter 5, Simple Input and Output.
Chapter 5. Simple Input and Output
This chapter explains how to use BASIC statements to move data to and from your program.
5.1. Program Input
You can enter data interactively while the program runs. You do this with the INPUT, INPUT LINE, and LINPUT statements.
If you know all the information your program will require, you can enter it as you write the program. You do this with the READ, DATA, and RESTORE statements, or you can name constants with the known values.
You can read data from files outside the program. You do this with the INPUT #, INPUT LINE #, and LINPUT # statements.
The following sections describe how to use these statements in detail.
5.1.1. Providing Input Interactively
The INPUT, INPUT LINE, and LINPUT statements prompt a user for data while the program runs.
5.1.1.1. INPUT Statement
INPUT "PLEASE TYPE 3 INTEGERS" ;B% ,C% ,D% A% = B% + C% + D% PRINT "THEIR SUM IS"; A% END
Output
PLEASE TYPE 3 INTEGERS?
25,50,75
Return
THEIR SUM IS 150
If you have a semicolon separating the input prompt string from the variable, BASIC prints the question mark and space immediately after the input prompt string.
If you have a comma separating the input prompt string from the variable, BASIC prints the input prompt string, skips to the next print zone, and then prints the question mark and space.
See Section 5.2.1, “Print Zones—The Comma and the Semicolon” for more information about print zones. For more information about formatting string prompts, see Section 5.1.1.3, “Enabling and Disabling the Question Mark Prompt”.
INPUT A,B END
Output
?
5 Return
?
6 Return
?
5 Return
?
Return
These responses assign the value 5 to variable A and zero to variable B. In contrast, if you provide more values than there are variables, BASIC ignores the excess.
INPUT A,B,C PRINT A,B,C END
Output
?
5,6,7,8 Return
5 6 7
If you name a numeric variable in an INPUT statement, you must supply numeric data. If you supply string data to a numeric variable, BASIC signals “Illegal number” (ERR=52). If you supply a floating-point number for an integer variable, BASIC signals “Data format error” (ERR=50).
INPUT "Please type a number"; A$ PRINT A$
Output
Please type a number? 25.5 25.5
BASIC interprets the response as a 4-character string instead of as a numeric value.
You can type strings with or without quotation marks. However, if you want to input a string containing a comma, you should enclose the string in quotation marks or use the INPUT LINE or LINPUT statement. If you do not, BASIC treats the comma as a delimiter and assigns only part of the string to the variable. If you use quotation marks, be sure to type both beginning and ending marks. If you leave out the end quotation mark, BASIC signals “Data format error” (ERR=50).
5.1.1.2. INPUT LINE and LINPUT Statements
The INPUT LINE and LINPUT statements prompt you for string data while your program runs. You can respond with strings that contain commas, semicolons, and quotation marks, which are characters that the INPUT statement interprets as delimiters.
The INPUT LINE statement accepts and stores all characters, including quotation marks, semicolons, and commas, up to and including the line terminator or terminators. LINPUT accepts all characters up to, but not including, the line terminator or terminators.
INPUT LINE A$ LINPUT B$ LINPUT C$ PRINT A$, B$, C$ PRINT "DONE" END
Output
? SINGLE, DOUBLE Return ? "GFLOAT" Return ? HFLOAT; REAL Data Types Return SINGLE, DOUBLE "GFLOAT" HFLOAT; REAL Data Types DONE
The INPUT, INPUT LINE, and LINPUT statements can accept data from a terminal or a terminal-format file. See Section 5.3, “Terminal-Format Files” for information about I/O to terminal-format files.
5.1.1.3. Enabling and Disabling the Question Mark Prompt
With the SET PROMPT statement, VSI BASIC for OpenVMS allows you to enable and disable the question mark prompt.
INPUT "Please input 3 integer values";A%, B%, C%
Output
Please input 3 integer values?
SET NO PROMPT INPUT "Please input 3 integer values";A%, B%, C%
Output
Please input 3 integer values
SET NO PROMPT INPUT "Please enter your name: ";Employee_name$
Output
Please enter your name:
SET PROMPT INPUT "Please enter your name: ";Employee_name$
Output
Please enter your name: ?
The SET PROMPT statement
The CHAIN statement
The NEW, OLD, RUN, or SCRATCH compiler command
5.1.2. Providing Input from the Source Program
The following sections describe the READ, DATA, and RESTORE statements. To use READ and DATA statements, you must know what data is required when writing the program. These statements do not stop to request data while the program runs; therefore, your program runs faster than with the INPUT statements.
The RESTORE statement lets you use the same data items more than once.
5.1.2.1. READ and DATA Statements
10 WHEN ERROR USE catch_it DATA 1%, 2%, 3% 20 READ A%, B%, C% END WHEN 400 HANDLER catch_it PRINT "ERROR NUMBER IS "; ERR PRINT "ERROR AT LINE "; ERL PRINT "ERROR MESSAGE IS "; ERT$(ERR) END HANDLER 500 END
Output
ERROR NUMBER IS 50 ERROR AT LINE 20 ERROR MESSAGE IS %Data format error
A READ statement is not valid without at least one DATA statement. If your program contains a READ statement but no DATA statement, BASIC signals the compile-time error “READ without DATA”.
READ statements can appear either before or after their corresponding DATA statements. The only restriction is that the DATA statements must be in the same order as their corresponding READ statements.
10 DATA "ABRAMS", BAKER, CHRISTENSON, & DOBSON, "EISENSTADT", FOLEY
READ A$ DATA ABC !COMMENT
When you compile a program, BASIC creates one data block for each program unit. Each data block is local to the program or subprogram containing it; this means that you cannot share DATA statements between program modules.
The data block contains the values in all DATA statements in that program unit. These values are stored in line number order. Each time BASIC executes a READ statement, it retrieves the next value in the data block.
Assign alphabetic characters to a numeric variable. BASIC signals “Data format error” (ERR=50).
Have more variables in the READ statements than there are values in the DATA statements. BASIC signals “Out of data” (ERR=57).
BASIC ignores excess data in DATA statements.
DATA "The circumference is" DATA 40.5 READ text$ READ radius CIRCUMFERENCE = PI * radius * 2 PRINT text$; CIRCUMFERENCE END
Output
The circumference is 254.469
5.1.2.2. RESTORE Statement
The RESTORE statement lets you read the same data more than once. It has no effect without READ and DATA statements.
10 READ B,C,D 20 RESTORE 30 READ E,F,G 40 DATA 6,3,4,7,9,2 50 END
- B=6
- C=3
- D=4
- E=6
- F=3
- G=4
- E=7
- F=9
- G=2
5.2. Program Output
The PRINT statement displays data on your terminal during program execution. BASIC evaluates expressions before displaying results. You can also print and format data with the PRINT USING statement. For information about the PRINT USING statement, see Chapter 14, Formatting Output with the PRINT USING Statement.
Precedes positive numbers with a space and negative numbers with a minus sign
Prints a space after every number
Prints strings without leading or trailing spaces
A = 45 B = 55 PRINT A + B END
Output
100
A = 45 B = 55 PRINT "A + B" END
Output
A + B
PRINT "This example leaves a blank line" PRINT PRINT "between two lines." END
Output
This example leaves a blank line between two lines.
5.2.1. Print Zones—The Comma and the Semicolon
A terminal line contains zones that are 14 character positions wide. The number of zones in a line depends on the width of your terminal: a 72-character line contains 5 zones, which start in columns 1, 15, 29, 43, and 57. A 132-character line has additional print zones starting at columns 71, 85, 99, and 113.
INPUT A ,B ,C ,D ,E ,F PRINT A ,B ,C ,D ,E ,F END
Output
? 5,10,15,20,25,30 Return
5 10 15 20 25
30
A = 5 B = 10 PRINT "first zone",,"third zone" PRINT A,,B END
Output
first zone third zone 5 10
PRINT 10; 20 PRINT "ABC"; "XYZ" END
Output
10 20 ABCXYZ
INPUT X,Y,Z PRINT X,Y, PRINT Z END
Output
? 5,10,15 5 10 15
!No comma after I%, so each element !Prints on its own line ! PRINT I% FOR I% = 1% TO 10% PRINT ! !A comma follows J%, so each !element prints in a separate zone ! MARGIN 80% PRINT J%, FOR J% = 1% TO 10% PRINT ! !A semicolon follows K%, so print !elements are packed together ! PRINT K%; FOR K% = 1% TO 10% END
Output
1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10
PRINT "first zone",,"third zone",,"fifth zone" END
Output
first zone third zone fifth zone
PRINT "abcdefghijklmnopqrstuvwxyz","pizza" PRINT "first zone","second zone","third zone"
Output
abcdefghijklmnopqrstuvwxyz pizza first zone second zone third zone
5.2.2. Output Format for Numbers and Strings
PRINT 'PRINTING "QUOTATION" MARKS' END
Output
PRINTING "QUOTATION" MARKS
When you print numeric fields, BASIC precedes each number with a space or a minus sign and follows it with a space.
BASIC does not print trailing zeros to the right of the decimal point. If all digits to the right of the decimal point are zeros, BASIC omits the decimal point as well.
When you print LONG integers, BASIC prints up to 10 significant digits.
When you print DECIMAL values, VSI BASIC for OpenVMS prints up to 31 digits.
If a floating-point number can be represented exactly by 6 decimal digits (or fewer) and, optionally, a decimal point, BASIC prints it that way.
When you print a floating-point number whose integer portion is 6 decimal digits or less (for example, 1234.567), BASIC rounds the number to 6 digits (1234.57). If the integer portion of the number is 7 decimal digits or larger, BASIC rounds the number to 6 digits and prints it in E format. See the VSI BASIC Reference Manual for more information about E format.
When you print a floating-point number with magnitude from 0.1 to 1, BASIC rounds it to 6 digits. When you print a floating-point number with more than 6 digits, and with magnitude smaller than 0.1, BASIC rounds it to 6 digits and prints it in E format.
The PRINT statement displays only up to 6 digits of precision for floating-point numbers. This corresponds to the precision of the SINGLE or SFLOAT data types. To display the extra digits in DOUBLE, GFLOAT, TFLOAT, or XFLOAT numbers, you must use the PRINT USING statement. See Chapter 14, Formatting Output with the PRINT USING Statement for more information about the PRINT USING statement.
FOR I = 1 TO 20 PRINT 2^(-I),I,2^I NEXT I END
Output
.5 1 2 .25 2 4 .125 3 8 .0625 4 16 .03125 5 32 .015625 6 64 .78125E-02 7 128 .390625E-02 8 256 .195313E-02 9 512 .976563E-03 10 1024 .488281E-03 11 2048 .244141E-03 12 4096 .12207E-03 13 8192 .610352E-04 14 16384 .305176E-04 15 32768 .152588E-04 16 65536 .767939E-05 17 131072 .38147E-05 18 262144 .190735E-05 19 524288 .953674E-06 20 .104858E+07
5.3. Terminal-Format Files
Terminal-format files let you perform simple I/O to disk files. The records in a terminal-format file must be accessed sequentially. That is, you must access the records in the file one by one, from the first to the last. You can add new records only at the end of the file.
Just as the INPUT, LINPUT, and INPUT LINE statements receive information from a terminal, the INPUT #, LINPUT #, and INPUT LINE # statements receive information from a terminal-format file. And, as the PRINT statement sends information to the terminal, the PRINT # statement sends information to a terminal-format file.
Terminal-format files are useful for creating files to be printed on a line printer, or for supplying a program with moderate amounts of input. However, if you want to use the same file for both input and output, you should not use terminal-format files. Instead, use sequential, relative, or indexed files. For more information, see Chapter 13, File Input and Output.
You do not have to use a program to create a terminal-format file. You can use a text editor to create a file and insert data, then use a BASIC program to open the file and retrieve the data.
5.3.1. Opening and Closing a Terminal-Format File
You use the OPEN statement to create a file, or to gain access to an existing file. If you do not specify either FOR INPUT or FOR OUTPUT in the OPEN statement, BASIC tries to open an existing file. If the file does not exist, BASIC creates a new one.
The channel specification lets you associate a number with the file for as long as the file is open. All I/O operations to or from the file use this number.
When you are finished accessing a file, you close it with the CLOSE statement.
5.3.2. Writing Records to a Terminal-Format File
PRINT "This program creates a daily sales report file named SALES.DAT" OPEN "SALES.DAT" FOR OUTPUT AS FILE #4% PRINT #4%, "Salesperson","Sales Area","Items Sold" PRINT #4% INPUT "How many salespersons for today's report"; sales_persons% FOR I% = 1% TO sales_persons% INPUT "Salesperson's name"; s_name$ INPUT "Sales area"; area$ INPUT "Number of items sold"; items_sold% PRINT #4%, s_name$, area$, items_sold% NEXT I% CLOSE #4% END
Output
This program creates a daily sales report file named SALES.DAT How many salespersons for today's report? 3 Salesperson's name? JONES Sales area? NJ Items sold? 5 Salesperson's name? SMITH Sales area? NH Items sold? 6 Salesperson's name? BAINES Sales area? VT Items sold? 8
This program first prints a header explaining its purpose, then opens a terminal-format file on channel 4. After this file is opened, the two PRINT # statements place an explanatory header followed by a blank line into the file.
The program then prompts you for the number of salespersons for which data is to be entered. The FOR...NEXT loop prompts for the name, sales area, and items sold for each salesperson. The FOR...NEXT loop executes only as many times as there are salespersons. See Chapter 9, Program Control for more information about FOR...NEXT loops.
After the data has been entered for each salesperson, the program writes this information to the terminal-format file. Because the response to the first question was 3, the FOR...NEXT loop executes three times.
$ TYPE SALES.DAT Salesperson Sales Area Items Sold JONES NJ 5 SMITH NH 6 BAINES VT 8
Chapter 6. Arrays
An array is a set of data that is ordered in any number of dimensions. This chapter describes how to create and use VSI BASIC for OpenVMS arrays.
6.1. Overview of Arrays
A one-dimensional array is called a list or vector. A two-dimensional array is called a matrix. VSI BASIC for OpenVMS arrays can have up to 32 dimensions, and a specific type of VSI BASIC for OpenVMS arrays can be redimensioned at run time. In addition, you can specify the data type of the values in an array by using data type keywords or suffixes.
The number of dimensions that the array contains
The range of values for the subscripts in each dimension of the array
BASIC arrays are zero-based by default; that is, when calculating the number of elements in a dimension, you count from zero to the number of elements specified. For example, an array with an upper bound of 10 and no specified lower bound has 11 elements: 0 to 10, inclusive. The array My_array(3,3) has 16 elements: 0 to 3 in each dimension, or 42.
DECLARE REAL Sales_data(1990 TO 1999)
PRINT Sales_data(1999)
You can create arrays either implicitly or explicitly. You implicitly create arrays having any number of dimensions by referencing an element of the array. If you implicitly create an array, BASIC sets the upper bound to 10 and the lower bound to zero. Therefore, any array that you create implicitly contains 11 elements in each dimension.
Student_grades(8) = "B"
You create arrays explicitly by declaring them in a DIM, DECLARE, COMMON, or MAP statement, or record declaration. Note that if you want to specify lower bounds for your array subscripts, you must declare the array explicitly.
When you declare an array explicitly, the value that you give for the upper bound determines the maximum subscript value in that dimension. If you specify a lower bound, then that is the minimum subscript value in that dimension. If you do not specify a lower bound, BASIC sets the lower bound in that dimension to zero. You can specify bounds as either positive or negative values. However, the lower bound of each dimension must always be less than or equal to the upper bound for that dimension.
You can use MAT statements to create and manipulate arrays; however, MAT statements are valid only on arrays of one or two dimensions. In addition, the lower bounds of all dimensions in an array referenced in a MAT statement must be zero.
6.2. Creating Arrays Explicitly
You can create arrays explicitly with four BASIC statements: DECLARE, DIMENSION, COMMON, and MAP.
In addition, you can declare arrays as components of a record data type. See Chapter 8, Creating and Using Data Structures for more information about records.
Use the DIM statement to create virtual arrays and arrays that can be redimensioned at run time.
Use the COMMON statement to create arrays that can be shared among program modules or to create arrays of fixed-length strings.
Use the MAP statement to create an array and associate it with a record buffer, or to overlay the storage for an array, thus accessing the same storage in different ways.
When you create an array, the bounds you specify determine the array's size. The maximum value allowed for a bound can be as large as 2147483467; however, this number is actually limited by the amount of virtual storage available to you. Very large arrays and arrays with many dimensions can cause fatal errors at both compile time and run time.
When referencing an array, you must use the same number of subscripts as was specified when the array was created.
You can use identical names for a simple variable and an array; for example, A% and A%(5,5). However, this is not a recommended programming practice. If you use identical names for arrays with a different number of subscripts, for example, A(5), and A(10,10), BASIC prints the error “Inconsistent subscript usage” at compile time.
- If subscript checking is enabled, VSI BASIC for OpenVMS signals the error “Subscript out of range” (ERR=55) if you reference an array element whose subscripts are one of the following:
Greater than the current upper bound of the array
Less than the current lower bound of the array
Less than zero where no lower bound was specified
6.2.1. Creating Arrays with the DECLARE Statement
DECLARE LONG FIRST_ARRAY(1980 TO 1990)
Note that the STRING data type with the DECLARE statement causes the creation of an array of dynamic strings. To create an array of fixed-length strings, declare the array in a COMMON or MAP statement or as part of a RECORD structure.
6.2.2. Creating Arrays with the DIM Statement
Redimension the array at run time
Create a virtual array
If the array name ends with a dollar sign ($), the array stores string data.
If the array name ends with a percent sign (%), the array stores integer data.
If the array name does not end with either a percent sign or a dollar sign, the array stores data of the default type. The default type is single-precision, floating-point unless you change the default. See Chapter 4, BASIC Concepts and Elements for more information about default data types.
Even if the DIM statement contains a data type keyword, the array name can still end in the appropriate data type suffix. This makes the data type of the array immediately obvious.
The DIM statement can be either executable or declarative. If the specified bounds are constants, the DIM statement is declarative. This means that the storage is allocated at compile time, and the array cannot appear in any other DIM statement.
Note
In the DIM statement, bounds can be either constants or variables (simple or subscripted), but not expressions.
When an array is redimensioned with the executable DIM statement, the array can become larger or smaller than it was. However, redimensioning an array in this way causes it to be reinitialized, and all data in the array is lost.
In contrast, MAT statements let you redimension an array to be the same size or smaller than it was. However, MAT statements redimension arrays only when assigning values or performing matrix I/O; therefore, the fact that MAT statements reinitialize the array does not matter. See Section 6.6, “Using MAT Statements” for more information about MAT statements.
6.2.2.1. Declarative DIM Statements
DIM #1%, STRING VIRT_ARRAY(100) = 256%
A declarative DIM statement must lexically precede any reference to the array it dimensions.
The lower bounds of all virtual array dimensions must be zero.
You must open a VIRTUAL file on the specified channel before you can access elements of the virtual array.
6.2.2.2. Executable DIM Statements
Executable DIM statements have at least one variable bound. Bounds can be constants or simple variables, but at least one bound must be a variable. Executable DIM statements let you redimension an array at run time. The bounds of the array can become larger or smaller, but the number of dimensions cannot change. For example, you cannot redimension a four-dimensional array to be five-dimensional.
The executable DIM statement cannot be used on arrays in COMMON, MAP, DECLARE, or declarative DIM statements, nor on virtual arrays or arrays received as formal parameters.
Whenever an executable DIM statement executes, it reinitializes the array. If you change the values of an executable DIM statement, the initial values are reset each time the DIM statement is executed.
X% = 10% Y% = 20% DIM real_array(X%) real_array(1%) = 100 PRINT real_array(1%) DIM real_array(Y%) PRINT real_array(1%) END
Output
100 0
You cannot reference an array named in an executable DIM statement until after the DIM statement executes. If you reference an array element declared in an executable DIM statement whose subscripts are larger than the bounds specified in the last execution of the DIM statement, BASIC signals the run-time error “Subscript out of range” (ERR = 55), provided subscript checking is enabled.
6.2.3. Creating Arrays with the COMMON Statement
Create arrays with the COMMON statement when you need an array of fixed-length strings, or when you want to share an array among program modules. Program modules can share arrays in COMMON statements by defining a common block with the same name.
!Main Program COMMON (ABC) STRING access_list(1 TO 100) = 10
!Subprogram SUB SUB1 COMMON (ABC) STRING new_list(1 TO 100) = 10
6.2.4. Creating Arrays with the MAP Statement
Create arrays with the MAP statement only when you want the array to be part of a record buffer, or when you want to overlay the storage containing the array. Note that string arrays in maps are always fixed-length.
You associate the array with a record buffer by naming the map in the MAP clause of the OPEN statement.
MAP (ABC) STRING team(10) = 20, WORD bowling_scores(0 TO 32) OPEN "BOWLING.DAT" AS FILE #1%, SEQUENTIAL VARIABLE, MAP ABC
6.3. Creating Arrays Implicitly
By referencing an element of an array that has not been explicitly declared
By using MAT statements
LET A(5,5,5) = 3.14159 LET B%(3) = 33 LET C$(2,2) = "Russell Scott" END
The first LET statement creates an 11-by-11-by-11 array that stores floating-point numbers and assigns the value 3.14159 to element (5,5,5). The second LET statement creates an 11-element list that stores integers and assigns the value 33 to element (3), and the third LET statement creates an 11-by-11 string array and assigns the value “Russell Scott” to element (2,2).
When you create an implicit numeric array by referring to an element, BASIC initializes all elements (except the one assigned a value) to zero. For implicit string arrays, BASIC initializes all elements (except the one assigned a value) to a null string. When you implicitly create an array, you cannot specify a subscript greater than 10. An attempt to do so causes BASIC to signal “Subscript out of range” (ERR = 55), provided that subscript checking is enabled.
Note that you cannot create an array implicitly, then redimension the array with an executable DIM statement. The DIM statement must execute before any reference to the array.
new_array (5,5,5) = 1 DECLARE LONG new_array (15,10,5)
6.4. Determining the Bounds of an Array
BASIC provides two built-in functions, LBOUND and UBOUND, that allow you to determine the lower and upper bounds, respectively, for any dimension in an array.
DECLARE Sales_data(1900 TO 1999, 1 TO 12) Month_start% = LBOUND (Sales_data, 2) Year_start% = LBOUND (Sales_data, 1) Month_end% = UBOUND (Sales_data, 2) Year_end% = UBOUND (Sales_data, 1) FOR Year% = Year_start% TO Year_end% FOR Month% = Month_start% TO Month_end% PRINT Sales_data(Year%, Month%) NEXT Month% NEXT Year%
Note
You cannot implicitly declare arrays with the LBOUND and UBOUND functions. These functions can be used only with arrays that have been previously declared.
6.5. Assigning and Displaying Array Values
The following sections explain how to access and write to BASIC arrays with the LET and PRINT statements.
6.5.1. Assigning Values with the LET Statement
DIM voucher_num%(100) . . . LET voucher_num%(20) = 3253% . . . END
DIM po_number%(100,100) . . . FOR I% = 1% TO 3% FOR J% = 5% TO 10% LET po_number%(I%,J%) = 0% NEXT J% NEXT I% . . . END
6.5.2. Listing Array Elements with the PRINT Statement
PRINT parts_list$(35%)
DIM capture_ratio(10,10) . . . FOR Y% = 7% TO 10% FOR X% = 7% TO 10% PRINT capture_ratio(X%,Y%) NEXT X% NEXT Y%
6.6. Using MAT Statements
Note
The MAT statements discussed in this section are not related to the MAT GRAPH and MAT PLOT graphics statements. For more information about these statements, see Programming with VAX BASIC Graphics.
Implicitly create arrays
Assign names to arrays
Specify array dimensions
Redimension existing arrays (to equal or smaller sizes)
Assign element values
Print the contents of arrays
Perform matrix arithmetic
Note
MAT statements cannot be used with arrays that have lower bounds other than zero. An attempt to specify a lower bound other than zero for an array in a MAT statement results in a compile-time error.
The default subscripts for arrays created implicitly with MAT statements are (10) or (10,10). The default is two dimensions. This means that if you create an array with a MAT statement and do not specify any subscripts, BASIC creates a two-dimensional, 11-by-11 array. If you specify a single subscript, BASIC creates a one-dimensional array with 11 elements.
Statement |
Function |
---|---|
MAT |
Assigns values of zero, 1, or a null string to array elements. Also copies the values of one array to another and performs matrix arithmetic. |
MAT READ |
Assigns DATA statement values to array elements. |
MAT INPUT [#] |
Assigns values to array elements from your terminal or a terminal-format file. |
MAT LINPUT [#] |
Assigns string values to string array elements from your terminal or from a terminal-format file. |
MAT PRINT [#] |
Displays the contents of an array on your terminal, or writes array element values to a terminal-format file. |
MAT z_array$ = NUL$(7,7) MAT z_array$ = NUL$(5,5) MAT A = B + C END
6.6.1. MAT Statement
MAT Keyword |
Function |
---|---|
ZER |
Sets the value of all elements in a numeric array to zero. |
CON |
Sets the value of all elements in a numeric array to 1, except those in row and column zero. |
IDN |
Sets the array to the identity matrix, that is, it sets the value of all elements in real or integer arrays to zero, except for those elements on the diagonal from element (1,1) to element (n,n), where n is the largest subscript in the array. The elements on the diagonal are set to 1. IDN applies to square arrays only. |
NUL$ |
Sets the value of all elements in a string array to the null string, except those in row and column zero. |
The array name can specify an existing array. MAT statements do not assign values to row and column zero.
If you do not specify subscripts, BASIC does not change the current subscripts.
If you specify subscripts, BASIC redimensions the array to the specified subscripts. When redimensioning arrays with MAT, you cannot increase the total number of array elements (including those in row and column zero).
If you do not supply subscripts, BASIC assigns two subscripts, each with a value of 10.
If you specify subscripts, they define the dimensions of the array being implicitly created. Subscript values cannot exceed 10. Consider the following example:
DIM A(10,10), B(15), C(20,20) MAT A = ZER !Sets all elements of A to 0 MAT B = CON(10) !Sets elements of B to 1; redimensions B MAT C = IDN(10,10) !Redimensions C to 10x10 identity matrix PRINT "ARRAY A:" MAT PRINT A; PRINT PRINT "ARRAY B:" MAT PRINT B; PRINT PRINT "ARRAY C:" MAT PRINT C;
Output
ARRAY A: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ARRAY B: 1 1 1 1 1 1 1 1 1 1 ARRAY C: 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
6.6.2. MAT READ Statement
The MAT READ statement assigns values from DATA statements to array elements. Subscripts define either the dimensions of the array being created or the new dimensions of an existing array; subscripts are optional in MAT READ statements.
If you do not provide enough data in DATA statements to fill the specified array, BASIC leaves the remaining array elements unchanged. If you provide more data values than there are array elements, BASIC assigns enough values to fill the array and leaves the DATA pointer at the next value.
MAT READ B(2,2) MAT READ C(2,2) PRINT PRINT "MATRIX B" PRINT PRINT MAT PRINT B; PRINT PRINT "MATRIX C" PRINT PRINT MAT PRINT C; DATA 1,2,3,4,5,6,7,8,9,10 END
Output
MATRIX B 1 2 3 4 MATRIX C 5 6 7 8
6.6.3. MAT INPUT [#] Statement
The MAT INPUT statement assigns values from your terminal to array elements. The MAT INPUT statement reads data from a terminal-format file and writes it to an array. The optional subscripts in a MAT INPUT statement define either the dimensions of the array being created implicitly or the new dimensions of an existing array. If you are implicitly creating the array, the value of a subscript cannot exceed 10.
The MAT INPUT statement requests data from your terminal, as does the INPUT statement; it prints a question mark (?) prompt that you can disable with the SET NO PROMPT statement and then enable with the SET PROMPT statement. However, you cannot include a string prompt with the MAT INPUT statement.
When you enter a series of values separated by commas, BASIC enters the values you supply into successive array elements by row, starting with element (1,1) and filling row 1 before starting row 2. If you provide fewer data items than there are elements, the remaining elements are unchanged. If you provide more items than there are elements, BASIC ignores the excess.
The MAT INPUT statement takes values from an open file and assigns them to the matrix elements by rows, starting with element (1,1). It fills the elements in row 1 before starting row 2. The file can have one or more values in each record; however, multiple values must be separated with commas.
MAT INPUT #3, A PRINT MAT PRINT A; MAT INPUT B(2,2) PRINT MAT PRINT B;
Output
1 2 3 4 5 6 7 8 9 10 11 12 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ? 1,2,3,4 1 2 3 4
Note that the MAT PRINT statement does not print row and column zero. For more information about the MAT PRINT statement, see Section 6.6.5, “MAT PRINT [#] Statement”.
DIM new_array%(5,5) MAT INPUT new_array%(2,4) MAT PRINT new_array%; END
Output
? 1,2,3,4,5,6,7,8 1 2 3 4 5 6 7 8
When entering values in response to MAT INPUT, you can enter an ampersand (&) as the last character on the line and continue on the next line.
6.6.4. MAT LINPUT [#] Statement
The MAT LINPUT statement assigns string values to string array elements. The MAT LINPUT statement reads string values from a terminal-format file and writes them to a string array.
DIM emp_nam$(5,5) MAT LINPUT emp_nam$(2,2) PRINT emp_nam$(1,1) PRINT emp_nam$(1,2) PRINT emp_nam$(2,1) PRINT emp_nam$(2,2) END
Output
? SMITH ? JONES ? WHITE ? BLACK SMITH JONES WHITE BLACK
By specifying the subscripts (2,2), MAT LINPUT redimensions the array to nine elements and overwrites the old values (assigning the values in the same manner as MAT INPUT; see Section 6.6.3, “MAT INPUT [#] Statement”). BASIC then prompts for these elements.
MAT LINPUT also excludes line terminators when assigning values to string array elements. MAT LINPUT places the values from the open file into the specified array, filling the array by rows, starting with element (1,1). If there are more values in the file than there are array elements, BASIC ignores the excess records. If there are fewer, BASIC assigns a null string to the remaining elements.
DIM part_name$(50) MAT LINPUT #1%, part_name$
6.6.5. MAT PRINT [#] Statement
The MAT PRINT statement prints some or all of an array's elements, excluding row and column zero. The MAT PRINT # statement takes values from an array by row, starting with element (1,1), and writes each element to a sequential record in the terminal-format file.
Subscripts are optional in MAT PRINT statements. If you do not specify subscripts, MAT PRINT displays the entire array, excluding row and column zero. If you specify subscripts, MAT PRINT displays the specified subset of the array. In the case of the MAT PRINT # statement, the subscripts determine how many array elements are written to the file. The MAT PRINT [#] statement does not redimension an existing array.
If the last character in the MAT PRINT [#] array list is a semicolon, BASIC begins each array row on a separate line. Data values on each line are packed together with no intermediate spaces. However, if the last character in the MAT PRINT [#] array list is a comma, BASIC begins each array row on a separate line and each data value in a separate print zone.
MAT INPUT A(5) PRINT MAT PRINT A PRINT MAT PRINT A, A; MAT PRINT #3, A, A; END
Output
? 5 5 0 0 0 0 5 0 0 0 0 5 0 0 0 0
6.6.6. Matrix I/O Functions (NUM and NUM2)
MAT statements do not signal error messages when there are more data items than array elements to contain them or when there are fewer data items than array elements to contain them.
BASIC provides two functions that let you determine how much data the MAT statements transfer: NUM and NUM2.
For two-dimensional arrays, the NUM function returns an integer value specifying the row number of the last data item transferred, and the NUM2 function returns an integer value specifying the column number of the last data item transferred. For one-dimensional arrays, the NUM function returns the number of items entered, and the NUM2 function returns a zero.
OPEN "EMP.DAT" FOR INPUT AS FILE #3% DIM emp_name$(5,5) MAT INPUT #3%, emp_name$ PRINT NUM, NUM2 END
Output
4 2
6.7. Matrix Operators
BASIC provides a special set of MAT statements for array computations. These statements enable you to add, subtract, and multiply matrices, and to assign values to elements. Note that if you specify an array without subscripts (for example, MAT A), the default is two dimensions.
Note
MAT operators do not operate on elements in row or column zero.
6.7.1. Arithmetic Matrix Operations
MAT operators perform matrix assignment, addition, subtraction, and multiplication.
Note
You can use the MAT operators on arrays larger than (10,10) if the input and output arrays are explicitly created or received as a formal parameter.
6.7.1.1. Assignment
MAT new_array = old_array
6.7.1.2. Addition and Subtraction
MAT sum_list% = first_list% + second_list%
DIM first_array(30,30) DIM second_array(30,30) DIM difference_array(30,30) . . . MAT difference_array = first_array - second_array
Each element of difference_array is the arithmetic difference of the corresponding elements of the input arrays.
6.7.1.3. Multiplication
DIM A(2,2), B(2,2), C(2,2) A(1,1) = 1 A(1,2) = 2 A(2,1) = 3 A(2,2) = 4 B(1,1) = 5 B(1,2) = 6 B(2,1) = 7 B(2,2) = 8 MAT C = A * B MAT PRINT C
19 22 43 50
DIM inch_array(5), cm_array(5) MAT READ inch_array DATA 1,12,36,100,39.37 MAT cm_array = (2.54) * inch_array MAT PRINT cm_array, END
Output
2.54 30.48 91.44 254 99.9998
6.7.2. Matrix Functions
- TRN
- INV
- DET
With these functions, you can transpose and invert matrices and find the determinant of an inverted matrix.
6.7.2.1. TRN Function
The TRN function transposes a matrix. When you transpose a matrix, BASIC interchanges the array's dimensions. For example, a matrix with n rows and m columns is transposed to a matrix with m rows and n columns. The elements in the first row of the input matrix become the elements in the first column of the output matrix. You cannot transpose a matrix to itself; MAT A = TRN(A) is invalid.
DIM B(3,5) MAT READ B MAT A = TRN(B) DATA 1,2,3,4,5 DATA 6,7,8,9,10 DATA 11,12,13,14,15 MAT PRINT B; MAT PRINT A; END
Output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 6 11 2 7 12 3 8 13 4 9 14 5 10 15
6.7.2.2. INV Function
MAT INPUT first_array(3,3) MAT PRINT first_array; PRINT MAT inv_array = INV (first_array) MAT PRINT inv_array; PRINT MAT mult_array = first_array * inv_array MAT PRINT mult_array; PRINT D = DET PRINT D
Output
? 4,0,0,0,0,2,0,8,0 4 0 0 0 0 2 0 8 0 .25 0 0 0 0 .125 0 .5 0 1 0 0 0 1 0 0 0 1 -64
Chapter 7. Data Definition
This chapter briefly describes how to define program objects, explicitly assign data types, and allocate and use data storage.
7.1. Declarative Statements
You use declarative statements to define objects in a VSI BASIC for OpenVMS program. Objects can be variables, arrays, constants, and user-defined functions within a program module. They can also be routines, variables, and constants external to the program module. Declarative statements always assign names to the objects declared and usually assign other attributes, such as a data type, to them. Declarative statements can also be used to define user-defined data types (RECORD statements). See Chapter 8, Creating and Using Data Structures for more information about the RECORD statement.
Variables
Arrays
Named constants
Values returned by functions
By declaring the objects used in your program, you make the program easier to understand, modify, and debug.
7.2. Data Types
At its most fundamental level, a data type is a format for information storage. All information is stored in the computer as bit patterns (groups of ones and zeros). Data types specify how the computer should interpret these patterns.
VSI BASIC for OpenVMS programs allow five general data types: integer, floating-point, string, packed decimal, and record. Each data type is suited for a particular type of task. For example, integers are useful for numeric computations involving whole numbers, strings provide a way to manipulate alphanumeric characters, and packed decimal data is useful for manipulating numeric values that require precise representation.
For more information about VSI BASIC for OpenVMS data types, see the VSI BASIC Reference Manual.
7.3. Setting the Default Data Type and Size
OPTION SIZE = INTEGER LONG
You can have more than one OPTION statement in a program module; however, OPTION statements can be preceded only by a SUB, FUNCTION, REM, or another OPTION statement.
Integer and packed decimal overflow checking
Program optimization
Rounding or truncation of packed decimal numbers
Subscript checking
See the VSI BASIC Reference Manual for more information about the OPTION statement.
OPTION TYPE = EXPLICIT, ! Variables must be declared & CONSTANT TYPE = INTEGER, ! All implicit constants be integers & SIZE = INTEGER LONG, ! 32-bit integers by default & SIZE = REAL DOUBLE ! 64-bit floating-point ! numbers by default
You can create variables of other data types by explicitly declaring them with the DECLARE, COMMON, or MAP statement.
7.4. Declaring Variables
Floating-point
Integer
String
RFA
Packed decimal
Record
For more information about declaring variables, see the VSI BASIC Reference Manual.
7.5. Declaring Named Constants
A constant is a value that does not change during program execution. You can declare named constants within a program unit with the DECLARE statement. You can also refer to constants outside the program unit with the EXTERNAL statement. In addition, BASIC provides notation for binary, octal, decimal, and hexadecimal constants.
For more information about named constants, see the VSI BASIC Reference Manual.
7.6. Operations with Multiple Data Types
When an expression contains operands of different data types, it is called a mixed-mode expression. Before a mixed-mode expression can be evaluated, the operands must be converted, or promoted, to a common data type. The result of the evaluation can also be converted depending on the data type of the variable to which it is assigned.
When assigning values to variables, VSI BASIC for OpenVMS converts the result of the expression to the data type of the variable. If the value of the expression is outside the allowable range of the variable's data type, VSI BASIC for OpenVMS signals “Integer error or overflow,” “Floating-point error or overflow,” or “DECIMAL error or overflow.”
In general, VSI BASIC for OpenVMS promotes operands with different data types to the lowest data type that can hold the largest and most precise possible value of either operand's data type. VSI BASIC for OpenVMS then performs the operation in that data type, and yields a result of that data type. If the result of the expression is assigned to a variable, VSI BASIC for OpenVMS converts the result to the data type of the variable. For more information about multiple data types, see the VSI BASIC Reference Manual.
7.7. Allocating Dynamic and Static Storage
VSI BASIC for OpenVMS programs allocate both dynamic and static storage. Dynamic storage is allocated when the program executes, whereas the size of static storage does not change during program execution.
DECLARE statements
DIMENSION statements
Implicitly declared variables
Normally, string variables and arrays declared in these ways are dynamic strings, and their length can change during program execution. However, if you declare or dimension an array of a user-defined data type (a RECORD name), then all string variables and arrays are fixed-length strings. See Chapter 8, Creating and Using Data Structures for more information about the RECORD statement.
Variables and arrays appearing in MAP or COMMON statements use static storage. Hence all string variables appearing in MAP or COMMON statements are fixed-length strings. MAP and COMMON statements create a named storage area called a program section, or PSECT. MAP statements require a map name, but in COMMON statements the name is optional. The PSECT name is the same as the map or common name. If you do not specify a common name, VSI BASIC for OpenVMS supplies a default PSECT name of $BLANK.
The remainder of this section explains how to use COMMON and MAP statements for static storage.
7.7.1. COMMON Statement
A numeric variable
A numeric array
A fixed-length string variable
An array of fixed-length strings
A RECORD instance
A FILL item
An RFA item
COMMON (code) STRING emp.code=2, wage.code=3, dep.code=22
COMMON (into) LONG call_count, sub1_count, sub2_count COMMON (into) LONG sub3_count, sub4_count
When you explicitly declare an array, VSI BASIC for OpenVMS allows you to specify both upper and lower bound values. The value you supply as the upper bound determines the maximum subscript value for a given dimension, and the value you supply for the lower bound determines the minimum subscript value for a given dimension.
For more information about specifying bounds with the COMMON statement, see Chapter 6, Arrays and the VSI BASIC Reference Manual.
7.7.2. MAP Statement
The MAP statement, like the COMMON statement, creates a named area of static storage. However, if a program module contains multiple maps with the same name, the maps are overlaid on the same area of storage, rather than being concatenated.
When used with the MAP clause of the OPEN statement, the storage allocated by the MAP statement becomes the record buffer for that file. Variables in the MAP statement correspond to fields in the file's records.
A numeric variable
A numeric array
A fixed-length string variable
An array of fixed-length strings
A RECORD instance
A FILL item
When you explicitly declare an array, VSI BASIC for OpenVMS allows you to specify both upper and lower bound values. The value you supply as the upper bound determines the maximum subscript value for a given dimension, and the value you supply for the lower bound determines the minimum subscript value for a given dimension.
For more information about specifying bounds with the MAP statement, see Chapter 6, Arrays and the VSI BASIC Reference Manual.
7.7.2.1. Single Maps
You associate a map with a record buffer by referencing the map in the OPEN statement.
The MAP statement must appear before any reference to map variables. Changes to map variables do not change the actual records in the file. To transfer the changed variables to the file, you must use the PUT or UPDATE statement. For more information, see Chapter 13, File Input and Output.
WHEN ERROR USE eof_handler DECLARE INTEGER CONSTANT EOF = 11 MAP (PAYROL) STRING emp_name, LONG wage_class, & STRING sal_rev_date, SINGLE tax_ytd OPEN "payroll.dat" FOR INPUT AS FILE #4% & ,ORGANIZATION SEQUENTIAL & ,ACCESS READ & ,MAP PAYROL OPEN "payrol.new" FOR OUTPUT AS FILE #5% & ,ORGANIZATION SEQUENTIAL & ,ACCESS WRITE & ,MAP payrol PRINT "PAYROLL VERIFICATION" get_loop: WHILE 1% = 1% GET #4 PRINT emp_name, wage_class, sal_rev_date, tax_ytd PRINT "YOU CAN CHANGE:" PRINT "1. EMPLOYEE NAME" PRINT "2. WAGE CLASS" PRINT "3. REVIEW DATE" PRINT "4. TAX YEAR-TO-DATE" PRINT "5. DONE" read_loop: WHILE 1% = 1% INPUT "CHANGES? ANSWER WITH YES OR NO" ; chng$ IF chng$ = "NO" THEN ITERATE get_loop ELSE INPUT "NUMBER" ;number% END IF SELECT number% CASE 1 INPUT "EMPLOYEE NAME"; emp_name CASE 2 INPUT "WAGE CLASS"; wage_class CASE 3 INPUT "REVIEW DATE";sal_rev_date CASE 4 INPUT "TAX YEAR-TO-DATE"; tax_ytd CASE 5 EXIT read_loop CASE ELSE PRINT "Invalid response -- please try again" END SELECT NEXT PUT #5 NEXT END WHEN HANDLER eof_handler IF ERR = EOF THEN PRINT "End of file" ELSE EXIT HANDLER END IF END HANDLER END
7.7.2.2. Multiple Maps
When a program contains more than one map with the same name, the storage allocated by these MAP statements is overlaid. This technique is useful for manipulating strings. Figure 7.1, “Multiple Maps” shows multiple maps and maps in use.
When you use more than one map to access a record buffer, VSI BASIC for OpenVMS uses the size of the largest map to determine the size of the record. (The RECORDSIZE clause of the OPEN statement can override this map-defined record size. For more information, see Chapter 13, File Input and Output.)
MAP (barray) BYTE alphabet(25) MAP (barray) STRING ABC = 26 FOR I% = 0% TO 25% alphabet(I%) = I% + 65% NEXT I% PRINT ABC END
Output
ABCDEFGHIJKLMNOPQRSTUVWXYZ
7.7.3. FILL Items
FILL items reserve space in map and common blocks and in record buffers accessed by MOVE or REMAP statements. Thus, FILL items mask parts of the record buffer and let you skip over fields and reserve space in or between data elements.
FILL Format |
Representation |
Bytes Used |
---|---|---|
FILL |
Floating-point |
4, 8, 16, or 32 |
FILL(n) |
n floating-point elements |
4 n, 8 n, 16 n, or 32 n |
FILL% |
Integer (BYTE, WORD, LONG, or QUAD) |
1, 2, 4, or 8 |
FILL%(n) |
n integer elements |
1 n, 2 n, 4 n, or 8 n |
FILL$ |
String |
16 |
FILL$(n) |
n string elements |
16 n |
FILL$ = m |
String |
m |
FILL$(n) = m |
n string elements, m bytes each |
m * n |
Note
In the applicable formats of FILL, n represents a repeat count, not an array subscript. FILL( n), for example, represents n real elements, not n+1.
MAP (QED) STRING A, FILL$=24, LONG SSN, FILL%, REAL SAL, FILL(5)
A 16-character string variable A
24 bytes of padding
One LONG variable, SSN
4 bytes of padding
One REAL variable, SAL
Space for five floating-point numbers (10, 20, or 80 bytes of padding, depending on the default size for floating-point numbers)
RECORD X REAL Y1, Y2(10) END RECORD X MAP (QED) X FILL
See Chapter 8, Creating and Using Data Structures for more information about the RECORD statement.
7.7.4. Using COMMON and MAP Statements in Subprograms
The COMMON and MAP statements create a block of storage called a PSECT. This common or map storage block is accessible to any subprogram. A VSI BASIC for OpenVMS main program and subprogram can share such an area by referencing the same common or map name.
A 16-character string field called A by the main program and X by the subprogram
A 10-character string field called B by the main program and Z by the subprogram
A 4-byte integer field called C by the main program and Y by the subprogram
!In a main program COMMON (A1) STRING A, B = 10, LONG C . . . !In a subprogram COMMON (A1) STRING X, Z = 10, LONG Y
If a subprogram defines a common or map area with the same name as a common or map area in the main program, it overlays the common or map defined in the main program.
COMMON (XYZ) STRING A = 32 COMMON (XYZ) STRING B = 32
!In the main program COMMON (XYZ) STRING A = 32 . . . !In the subprogram COMMON (XYZ) STRING B = 32
COMMON (SHARE) WORD emp_num, & DECIMAL (8,0) salary, & STRING wage_class = 2 . . . !In the main program %INCLUDE "COMMON.BAS" . . . !In the subprogram %INCLUDE "COMMON.BAS"
If you use the %INCLUDE directive, you can lessen the risk of a typographical error. For more information about using the %INCLUDE directive, see Chapter 16, Compiler Directives.
MAP (REDEF) STRING full_name = 40 . . . !In the main program %INCLUDE "MAP.BAS" . . . !In the subprogram %INCLUDE "MAP.BAS" MAP (REDEF) STRING first_name=15, MI=1, last_name=24
7.7.5. Dynamic Mapping
A declarative statement, such as a MAP statement, allocating a fixed-length storage area
A MAP DYNAMIC statement, naming the variables whose positions can change at run time
A REMAP statement, specifying the new positions of the variables named in the MAP DYNAMIC statement
The MAP DYNAMIC statement does not affect the amount of storage allocated. The MAP DYNAMIC statement causes VSI BASIC for OpenVMS to create internal pointers to the variables and array elements. Until your program executes the REMAP statement, the storage for each variable and each array element named in the MAP DYNAMIC statement starts at the beginning of the map storage area.
The MAP DYNAMIC statement is nonexecutable. With this statement, you cannot specify a string length. All string items have a length of zero until the program executes a REMAP statement.
The REMAP statement specifies the new positions of variables named in the MAP DYNAMIC statement. That is, it causes VSI BASIC for OpenVMS to change the internal pointers to the data. Because the REMAP statement is executable, it can redefine the pointer for a variable or array element each time the REMAP statement is executed.
With the MAP DYNAMIC statement, you can specify either a map name or a previously declared static string variable. When you specify a map name, a MAP statement with the same map name must lexically precede the MAP DYNAMIC statement.
DECLARE LONG CONSTANT emp_fixed_info = 4 + 9 + 2 MAP (emp_buffer) LONG badge, & STRING social_sec_num = 9, & BYTE name_length, & address_length, & FILL (60) MAP DYNAMIC (emp_buffer) STRING emp_name, & emp_address WHILE 1% GET #1 REMAP (emp_buffer) STRING FILL = emp_fixed_info, & emp_name = name_length, & emp_address = address_length NEXT
At the start of program execution, the storage for badge is the first 4 bytes of emp_buffer, the storage for social_sec_num is equal to 9 bytes, and together name_length and address_length are equal to 2 bytes. The FILL keyword reserves 60 additional bytes of storage. The MAP DYNAMIC statement defines the variables emp_name and emp_address whose positions and lengths will change at run time. When executed, the REMAP statement defines the FILL area to be equal to emp_fixed_info and defines the positions and lengths of emp_name and emp_address.
When you specify a static string variable, it must be either a variable declared in a MAP or COMMON statement or a parameter declared in a SUB, FUNCTION, PICTURE, or DEF. The actual parameter passed to the procedure must be a static string variable defined in a COMMON, MAP, or RECORD statement.
SUB deblock (STRING input_rec, STRING item()) MAP DYNAMIC (input_rec) STRING A(1 TO 3) REMAP (input_rec) & A(1) = 5, & A(2) = 3, & A(3) = 4 FOR I = LBOUND(A) TO UBOUND(A) item(I) = A(I) NEXT I END SUB
Note that dynamic map variables are local to the program module in which they reside; therefore, REMAP only affects how that module views the buffer.
For more information about using the MAP DYNAMIC and REMAP statements, see the VSI BASIC Reference Manual.
Chapter 8. Creating and Using Data Structures
A data structure is a collection of data items that can contain elements or components of different data types.
The RECORD statement lets you create your own data structures. You use the RECORD statement to create a pattern of a data structure, called the RECORD template. Once you have created a template, you use it to declare an instance of the RECORD, that is, a RECORD variable. You declare a RECORD variable just as you declare a variable of any other type: with the DECLARE statement or another declarative statement. A RECORD instance is a variable whose structure matches that of the RECORD template.
The RECORD statement does not create any variables. It only creates a template, or user-defined data type, that you can then use to create variables.
This chapter describes how to create and use data structures.
8.1. RECORD Statement
Variables of any valid BASIC data type
RECORD variables of previously defined RECORD data types
Any combination of the two
RECORD Employee LONG Emp_number STRING First_name = 10 STRING Last_name = 20 STRING Soc_sec_number = 11 END RECORD Empolyee
DECLARE Employee Emp_rec DECLARE Employee Emp_array (1000)
! Record Template RECORD Employee LONG Emp_number STRING First_name = 10 STRING Last_name = 20 STRING Soc_sec_number = 11 END RECORD Employee ! Declarations DECLARE Employee Emp_rec DECLARE STRING Social_security ! Program logic starts here. INPUT 'Employee number'; Emp_rec::Emp_number INPUT 'First name'; Emp_rec::First_name INPUT 'Last name'; Emp_rec::Last_name INPUT 'Social security'; Social_security IF Social_security <> "" THEN Emp_rec::Soc_sec_number = Social_security END IF PRINT PRINT "Employee number is: "; Emp_rec::Emp_number PRINT "First name is: "; Emp_rec::First_name PRINT "Last name is: "; Emp_rec::Last_name PRINT "Social security is: "; Emp_rec::Soc_sec_number END
! Record Template RECORD Employee LONG Emp_number STRING First_name = 10 STRING Last_name = 20 STRING Soc_sec_number = 11 END RECORD ! Declarations DECLARE Employee Emp_array ( 10 ) DECLARE INTEGER Index DECLARE STRING Social_security ! Program logic starts here. FOR Index = 0 TO 10 PRINT INPUT 'Employee number'; Emp_array(Index)::Emp_number INPUT 'First name'; Emp_array(Index)::First_name INPUT 'Last name'; Emp_array(Index)::Last_name INPUT 'Social security'; Social_security IF Social_security <> "" THEN Emp_array(Index)::Soc_sec_number = Social_security END IF NEXT Index FOR Index = 0 TO 10 PRINT PRINT "Employee number is: "; Emp_array(Index)::Emp_number PRINT "First name is: "; Emp_array(Index)::First_name PRINT "Last name is: "; Emp_array(Index)::Last_name PRINT "Social security is: "; Emp_array(Index)::Soc_sec_number NEXT Index END
RECORD Grade_record STRING Student_name = 30 INTEGER Quiz_scores (1 TO 10) ! Array to hold ten quiz grades. END RECORD ! Declarations DECLARE Grade_record Student_grades ( 5 ) !The Student_grades array holds information on six students !(0 through 5), each of whom has ten quiz grades (1 through 10). DECLARE INTEGER I,J !Program logic starts here. FOR I = 0 TO 5 !This loop executes once for each student. PRINT INPUT 'Student name'; Student_grades(I)::Student_name FOR J = 1 TO 10 !This loop executes ten times for each student. PRINT 'Score for quiz number'; J INPUT Student_grades(I)::Quiz_scores(J) NEXT J NEXT I FOR I = 0 TO 5 PRINT PRINT 'Student name: '; Student_grades(I)::Student_name FOR J = 1 TO 10 PRINT 'Score for quiz number'; J; ": "; PRINT Student_grades(I)::Quiz_scores(J) NEXT J NEXT I END
Because any reference to a component of a RECORD instance must begin with the name of the RECORD instance, RECORD component names need not be unique in your program. For example, you can have a RECORD component called First_name in any number of different RECORD statements. References to this component are unambiguous because every RECORD component reference must specify the record instance in which it resides.
8.1.1. Grouping RECORD Components
A RECORD component can consist of a named group of instances, identified with the keyword GROUP. You use GROUP to refer to a collection of RECORD components, or to create an array of components that have different data types. The GROUP name can be followed by a list of upper and lower bounds, which define an array of the GROUP components. GROUP is valid only within a RECORD block.
The declarations between the GROUP statement and the END GROUP statement are called a GROUP block.
RECORD Yacht GROUP Type_of_yacht STRING Manufacturer = 10 STRING Model = 10 END GROUP Type_of_yacht GROUP Specifications STRING Rig = 6 STRING Length_over_all = 3 DECIMAL(5,0) Displacement DECIMAL(2,0) Beam DECIMAL(7,2) Price END GROUP Specifications END RECORD Yacht
8.1.2. RECORD Variants
Sometimes it is useful to have different record components overlay the same record field, in much the same way that multiple maps can overlay the same storage. Such an overlay is called a RECORD variant. You use the keywords VARIANT and CASE to set up RECORD variants.
RECORD Boat STRING Make = 10 STRING Model = 10 STRING Type_of_boat = 1 ! This field contains the value S, P, or C. ! Value S causes the record instance to be ! interpreted as describing a sailboat, value ! P as describing a powerboat, and value C as ! describing a canoe. VARIANT CASE ! Sailboats STRING Rig = 20 CASE ! Powerboats WORD Horsepower CASE ! Canoes WORD Length WORD Weight END VARIANT END RECORD
! Declarations DECLARE Boat My_boat ! Main program logic starts here . . . Input_boat_information: INPUT 'Make of boat'; My_boat::Make INPUT 'Model'; My_boat::Model PRINT 'Type of boat (S = Sailboat, P = Powerboat, C = Canoe)'; INPUT My_boat::Type_of_boat SELECT My_boat::Type_of_boat CASE "S" INPUT 'Sail rig'; My_boat::Rig CASE "P" INPUT 'Horsepower'; My_boat::Horsepower CASE "C" INPUT 'Length'; My_boat::Length INPUT 'Weight'; My_boat::Weight CASE ELSE PRINT "Invalid type of boat, please try again." END SELECT
The value of the Type_of_boat component determines the format of the variant part of the record.
!Record templates RECORD Emp_wage_class STRING Emp_name = 30 ! Employee name string. STRING Street = 15 ! STRING City = 20 ! These components make up the STRING State = 2 ! employee address field. DECIMAL(5,0) Zip ! STRING Wage_class = 1 VARIANT CASE GROUP Hourly ! Hourly workers. DECIMAL(4,2) Hourly_wage ! Hourly wage rate. SINGLE Regular_pay_ytd ! Regular pay year-to-date. SINGLE Overtime_pay_ytd ! Overtime pay year-to-date. END GROUP Hourly CASE GROUP Salaried ! Salaried workers. DECIMAL(7,2) Yearly_salary ! Yearly salary. SINGLE Pay_ytd ! Pay year-to-date. END GROUP Salaried CASE GROUP Executive ! Executives. DECIMAL(8,2) Yearly_salary ! Yearly salary. SINGLE Pay_ytd ! Pay year-to-date. SINGLE Expenses_ytd ! Expenses year-to-date. END GROUP Executive END VARIANT END RECORD ! Declarations: DECLARE Emp_wage_class Emp ! Main Program logic starts here. LINPUT "Name"; Emp::Emp_name ! Use LINPUT statements for LINPUT "Street"; Emp::Street ! string fields so the entire ! string is assigned to the LINPUT "State"; Emp::State ! variable. INPUT "Zip Code"; Emp::Zip LINPUT "Wage Class"; Emp::Wage_class SELECT Emp::Wage_class CASE "A" INPUT 'Rate';Emp::Hourly_wage INPUT 'Regular pay';Emp::Regular_pay_ytd INPUT 'Overtime pay';Emp::Overtime_pay_ytd CASE "B" INPUT 'Salary';Emp::Salaried::yearly_salary INPUT 'Pay YTD';Emp::Salaried::pay_ytd CASE "C" INPUT 'Salary';Emp::Executive::yearly_salary INPUT 'Pay YTD';Emp::Executive::pay_ytd INPUT 'Expenses';Emp::Expenses_ytd END SELECT
Variant fields can appear anywhere within the RECORD instance. When you use RECORD variants, you imply that any RECORD instance can contain any one of the listed variants. Therefore, if each variant requires a different amount of space, BASIC uses the case that requires the most storage to determine the space allocated for each RECORD instance.
8.1.3. Accessing RECORD Components
To access a particular elementary component within a RECORD that contains other groups, you use the name of the declared RECORD instance, the group name (or group names, if groups are nested), and the elementary component name, each separated by double colons (::).
DECLARE Yacht My_yacht . . . PRINT My_yacht::Specifications::Rig
A RECORD contains more than one component with the same name
The GROUP is an array
You must always specify the RECORD instance, that is, the name of the declared variable.
You must always specify any dimensioned group.
You may omit any other intermediate component names.
You must specify the final component name.
! RECORD templates: RECORD Family GROUP Extended_family STRING Grandfather(1) = 30 ! Two-element fixed-length string STRING Grandmother(1) = 30 ! arrays for the names of maternal ! and paternal grandparents. GROUP Nuclear_family STRING Father = 30 ! Fixed-length strings for the names STRING Mother = 30 ! of parents. GROUP Children (10) ! An 11-element array for the names and ! gender of children. STRING Kid = 10 STRING Gender = 1 END GROUP Children END GROUP Nuclear_family END GROUP Extended_family END RECORD ! Declarations DECLARE Family My_family ! Program logic starts here. My_family::Extended_family::Nuclear_family::Children(1)::Kid = "Johnny" PRINT My_family::Children(1)::Kid END
Output
Johnny
! RECORD Templates. RECORD Test INTEGER Test_integers(2) ! 3-element array of integers. GROUP Group_1 ! Single GROUP containing: REAL My_number ! a real number and STRING Group_1_string ! a 16-character (default) string END GROUP GROUP Group_2(5) ! A 6-element GROUP, each element containing: INTEGER My_number ! an integer and DECIMAL Group_2_decimal ! a DECIMAL number. END GROUP END RECORD ! Declarations DECLARE Test Array_of_test(10) ! Create an 11-element array of type Test... DECLARE Test Single_test ! ...and a separate single instance of type ! Test.
Array_of_test(i)::Group_1_string
In this case, i is the subscript for array Array_of_test. Because the RECORD instance is itself an array, the reference must include a specific array element.
Single_test::Group_1_string
Array_of_test(i)::Group_1::My_number
Single_test::Group_1::My_number
Because there is a variable named My_number in groups Group_1 and Group_2, you must specify either Group_1::My_number or Group_2(i)::My_number. In this case, extra component names are required to resolve an otherwise ambiguous reference.
Array_of_test(i)::Group_2(j)::Group_2_decimal Single_test::Group_2(j)::Group_2_decimal
You can assign all the values from one RECORD instance to another RECORD instance, as long as the RECORD instances are identical except for names.
!RECORD Templates RECORD Test1 GROUP Group_1(4) STRING My_string_1 = 10 REAL My_real_1 INTEGER My_integer_1 END GROUP END RECORD RECORD Test2 GROUP Group_2 STRING My_string_2 = 10 REAL My_real_2 INTEGER My_integer_2 END GROUP END RECORD RECORD Test3 STRING My_string_3 = 10 REAL My_real_3 INTEGER My_integer_3 END RECORD !Declarations DECLARE Test1 First_test1, & Second_test1, & Array_of_test1(3) DECLARE Test2 First_test2 DECLARE Test3 First_test3, & Array_of_test3(10) !Program logic starts here ! A single RECORD instance is assigned to another single instance First_test1 = Second_test1 ! An array element is assigned to a single instance Second_test1 = Array_of_test1(2) ! And vice versa Array_of_test1(2) = Second_test1
Further, you can assign values from single RECORD instances to groups contained in other instances.
! A single instance is assigned to one group Array_of_test1(3)::Group_1(2) = First_test1 ! An array element is assigned a value from ! a group contained in another array instance Array_of_test3(5) = Array_of_test1(3)::Group_1(3)
The examples shown in this chapter explain the mechanics of using data structures. See Chapter 12, Program Segmentation for more information about using data structures as parameters. See Chapter 13, File Input and Output for more information about using data structures for file input and output.
Chapter 9. Program Control
This chapter describes the VSI BASIC for OpenVMS control statements.
Statement modifiers control the execution of a single statement.
Loops or decision blocks control the execution of a block of statements.
Branching statements such as GOTO and ON GOTO pass control to statements or local subroutines.
The EXIT and ITERATE statements explicitly control loops or decision blocks.
The SLEEP, WAIT, STOP and END control statements suspend or halt the execution of your entire program.
9.1. Statement Modifiers
- IF
- UNLESS
- FOR
- UNTIL
- WHILE
A statement modifier affects only the statement immediately preceding it. You can modify only executable statements; declarative statements cannot be modified.
9.1.1. IF Modifier
PRINT A IF (A < 5)
9.1.2. UNLESS Modifier
PRINT A UNLESS (A < 5)
PRINT A IF A >= 5
9.1.3. FOR Modifier
A = A + 1 FOR I% = 1% TO 10%
9.1.4. UNTIL Modifier
B = B + 1 UNTIL (A - B) < 0.0001
9.1.5. WHILE Modifier
A = A / 2 WHILE ABS(A) > 0.1
9.1.6. Nesting Modifiers
If you append more than one modifier to a statement, you are nesting modifiers. VSI BASIC for OpenVMS evaluates nested modifiers from right to left. If the test of the rightmost modifier fails, control passes to the next statement, not to the preceding modifier on the same line.
A = 5 B = 10 C = 15 PRINT "A =";A IF A = 5 UNLESS C = 15 PRINT "B =";B UNLESS C = 15 IF B = 10 PRINT "C =";C IF B = 10 UNLESS C = 5 END
Output
C = 15
9.2. Loops
- FOR...NEXT
- WHILE...NEXT
- UNTIL...NEXT
Note that these types of loops can be nested, that is, lexically located one inside another.
9.2.1. FOR...NEXT Loops
In a FOR...NEXT loop, you specify a loop control variable (the loop index) that determines the number of loop iterations. This number must be a scalar (unsubscripted) variable. When VSI BASIC for OpenVMS begins execution of a FOR...NEXT loop, the starting and ending values of the loop control variable are known.
The FOR statement assigns the control variable a starting value and an ending value. You can use the optional STEP clause to specify the amount to be added to the loop control variable after each loop iteration.
Evaluates the starting value and assigns it to the control variable.
Evaluates the ending value and the step value and assigns these results to temporary storage locations.
Tests whether the ending value has been exceeded. If the ending value has already been exceeded, VSI BASIC for OpenVMS executes the statement following the NEXT statement. If the ending value has not been exceeded, VSI BASIC for OpenVMS executes the statements in the loop.
Adds the step value to the control variable and transfers control to the FOR statement, which tests whether the ending value has been exceeded. Steps 3 and 4 are repeated until the ending value is exceeded.
Note that VSI BASIC for OpenVMS performs the test before the loop executes. When the control variable exceeds the ending value, VSI BASIC for OpenVMS exits the loop, and then subtracts the step value from the control variable. This means that after loop execution, the value of the control variable is the value last used in the loop, not the value that caused loop termination.
FOR I% = 1% TO Days_in_month Sales_data(I%) = Quantity_sold NEXT I%
counter% = 0% INPUT "Start"; start% INPUT "Finish"; finish% INPUT "Step value"; step_val% FOR I% = start% TO finish% STEP step_val% counter% = counter% + 1% NEXT I% PRINT "This loop executed"; counter%; "times."
Output
Start? 0 Finish? 5 Step value? -1 This loop executed 0 times.
Whenever possible, you should use integer variables to control the execution of FOR...NEXT loops because some decimal fractions cannot be represented exactly in a binary computer, and the calculation of floating-point control variables is subject to this inherent imprecision.
Loop_count_1 = 0% Loop_count_2 = 0% FOR Integer_variable = 1% to 100% STEP 1% Loop_count_1 = Loop_count_1 + 1% NEXT Integer_variable FOR Floating_point_variable = 0.1 to 10 STEP 0.1 Loop_count_2 = Loop_count_2 + 1% NEXT Floating_point_variable PRINT "Integer loop count:"; Loop_count_1 PRINT "Integer loop end :"; Integer_variable PRINT "Real loop count: "; Loop_count_2 PRINT "Real loop end: "; Floating_point_variable
Output
Integer loop count: 100 Integer loop end: 100 Real loop count: 99 Real loop end: 9.9
Although it is not recommended programming practice, you can assign a value to a FOR...NEXT loop's control variable while in the loop. This affects the number of times a loop executes. For example, assigning a value that exceeds the ending value of a loop will cause the loop's execution to end as soon as VSI BASIC for OpenVMS performs the termination test in the FOR statement. Assigning values to ending or step variables, however, has no effect at all on the loop's execution.
9.2.2. WHILE...NEXT Loops
A WHILE...NEXT statement uses a conditional expression to control loop execution; the loop is executed as long as a given condition is true. A WHILE...NEXT loop is useful when you do not know how many loop iterations are required.
INPUT 'Type "DONE" when finished'; Answer WHILE (Answer <> "DONE") . . . INPUT "More data"; Answer NEXT
Note that the NEXT statement in the WHILE...NEXT and UNTIL...NEXT loops does not increment a control variable; your program must change a variable in the conditional expression or the loop will execute indefinitely.
The evaluation of the conditional expression determines whether the loop executes. The test is performed (that is, the conditional expression is evaluated) before the first iteration; if the value is false (0), the loop does not execute.
It can be useful to intentionally create an infinite loop by coding a WHILE...NEXT loop whose conditional expression is always true. When doing this you must take care to provide a way out of the loop. You can do this with an EXIT statement or by trapping a run-time error. See Chapter 15, Handling Run-Time Errors for more information about trapping run-time errors.
9.2.3. UNTIL...NEXT Loops
The UNTIL...NEXT loop performs like a WHILE...NEXT loop, except that the logical sense of the conditional expression is reversed; that is, the UNTIL...NEXT loop executes until a given condition is true.
An UNTIL...NEXT loop executes repeatedly for as long as the conditional expression is false. Note that in UNTIL...NEXT loops, the NEXT statement does not increment a control variable. You must explicitly change a variable in the conditional expression or the loop will execute indefinitely.
INPUT 'Type "DONE" when finished.'; Answer UNTIL (Answer = "DONE") . . . INPUT "More data"; Answer NEXT
9.2.4. Nesting Loops
When a loop block is entirely contained in another loop block, it is called a nested loop.
DECLARE INTEGER Column_number, Row_number REAL Sales_info, Two_dim_array (15%, 15%) FOR Row_number = 0% TO 15% FOR Column_number = 0% to 15% INPUT "Please enter the sales information";Sales_info Two_dim_array (Row_number, Column_number) = Sales_info NEXT Column_number NEXT Row_number
Note that in nested loops the inner loop is entirely contained in the outer loop; nested loops cannot overlap.
9.3. Unconditional Branching (GOTO Statement)
The GOTO statement specifies which program line the VSI BASIC for OpenVMS compiler is to execute next, regardless of that line's position in the program. If the statement at the target line number or label is nonexecutable (such as an REM statement), VSI BASIC for OpenVMS transfers control to the next executable statement following the target line number.
You can use a GOTO statement to exit from a loop; however, it is better programming practice to use the EXIT statement.
9.4. Conditional Branching
ON...GOTO...OTHERWISE
IF...THEN...ELSE
SELECT...CASE
9.4.1. ON...GOTO...OTHERWISE Statement
Menu: PRINT "Would you like to change:" PRINT "1. First name" PRINT "2. Last name" INPUT CHOICE% ON CHOICE% GOTO First_name, Last_name OTHERWISE Other_choice First_name: INPUT "First name"; firstname$ GOTO Done Last_name: INPUT "Last name"; lastname$ GOTO Done Other_choice: PRINT "Invalid choice" PRINT "Let's try again" GOTO Menu Done: END
Note that if you do not supply an OTHERWISE clause and the control variable is less than 1 or greater than the number of targets, BASIC signals “ON statement out of range (ERR = 58)”.
9.4.2. IF...THEN...ELSE Statement
The IF...THEN...ELSE statement evaluates a conditional expression and uses the result to determine which block of statements to execute next. If the conditional expression is true, VSI BASIC for OpenVMS executes the statements in the THEN clause. If the conditional expression is false, VSI BASIC for OpenVMS executes the statements in the ELSE clause, if one is present. If the conditional expression is false and there is no ELSE clause, VSI BASIC for OpenVMS executes the statement immediately following the END IF statement.
INPUT "Input number"; number IF (number < 0) THEN number = - number PRINT "That square root is imaginary" PRINT "The square root of its absolute value is"; PRINT SQR(number) ELSE PRINT "The square root is"; SQR(number) END IF END
Output
Input number? -9 That square root is imaginary The square root of its absolute value is 3
Do not neglect to end an IF...THEN...ELSE statement. After an IF block is executed, control is transferred to the statement immediately following the END IF. If there is no END IF, VSI BASIC for OpenVMS transfers control to the next line number. Code between the keyword ELSE and the next line number becomes part of the ELSE clause. If there are no line numbers, the VSI BASIC for OpenVMS compiler ignores the remaining program code from the keyword ELSE to the end of the program. Therefore, it is important to end IF statements.
IF expression THEN IF expression THEN statement-list ELSE IF expression THEN statement-list ELSE statement-list ELSE
10 DECLARE INTEGER light_bulb DECLARE INTEGER circuit_switch DECLARE INTEGER CONSTANT Opened = 0 DECLARE INTEGER CONSTANT Closed = 1 PRINT "Please enter zero or one, corresponding to the circuit" PRINT "switch being open or closed" INPUT On_off_val IF On_off_val = Opened THEN PRINT "The light bulb is off." ELSE PRINT "The light bulb is on." END IF IF On_off_val = Closed THEN PRINT "The light bulb is on." ELSE PRINT "The light bulb is off." PRINT "That's all for now." 20 END
Output 1
Please enter zero or one, corresponding to the circuit switch being open or closed ? 0 The light bulb is off. The light bulb is off. That's all for now.
Output 2
Please enter zero or one, corresponding to the circuit Switch being open or closed ? 1 The light bulb is on. The light bulb is on.
IF A = B THEN PRINT A IF A = 3 ELSE PRINT B IF B > 0 END IF
9.4.3. SELECT...CASE Statement
The SELECT...CASE statement lets you specify an expression (the SELECT expression), any number of possible values (cases) for the SELECT expression, and a list of statements (a CASE block) for each case. The SELECT expression can be a numeric or string value. CASE values can be single or multiple values, one or more ranges of values, or relationships. When a match is found between the SELECT expression and a CASE value, the statements in the following CASE block are executed. Control is then transferred to the statement following the END SELECT statement.
DECLARE REAL Stock_change INPUT "Please enter stock price change";Stock_change SELECT Stock_change CASE <= 0.5 PRINT "Don't sell yet." CASE <= 1.0 PRINT "Sell today." CASE ELSE PRINT "Sell NOW!" END SELECT END
Output
Please enter stock price change? 2.1 Sell NOW!
If no match is found for any of the specified cases and there is no CASE ELSE block, VSI BASIC for OpenVMS transfers control to the statement following END SELECT without executing any of the statements in the SELECT block.
! This program is a skeleton command processor. ! It recognizes three VAX BASIC Environment commands: ! ! SAVE ! SCRATCH ! OLD DECLARE INTEGER CONSTANT True = -1 DECLARE INTEGER CONSTANT False = 0 DECLARE STRING CONSTANT Null_input = "" !This is the null string. DECLARE STRING Command ! Main program logic starts here. Command_loop: WHILE True ! This loop executes until the user types only a ! carriage return in response to the prompt. PRINT PRINT "Please enter a command (uppercase only)." PRINT "Type a carriage return when finished." INPUT Command PRINT SELECT Command CASE Null_input ! If user types RETURN, ! exit from the loop GOTO Done ! and end the program. ! The next three cases use the SEG$ and LEN string functions. ! LEN returns the length of the typed string, and SEG$ searches ! the string literals ("SAVE", "SCRATCH", and "OLD") for a ! match up to that length. Note that if the user types an "S", ! it is interpreted as a SAVE command only because SAVE is the ! first case tested. CASE SEG$ ( "SAVE", 1%, LEN (Command) ) PRINT "That was a SAVE command." CASE SEG$ ( "SCRATCH", 1%, LEN (Command) ) PRINT "That was a SCRATCH command." CASE SEG$( "OLD", 1%, LEN (Command) ) PRINT "That was an OLD command." CASE ELSE PRINT "Invalid command, please try again." END SELECT NEXT Done: END
9.5. EXIT and ITERATE Statements
This section describes the EXIT and ITERATE statements and shows their use with nested control structures.
The ITERATE and EXIT statements let you explicitly control loop execution. These statements can be used to transfer control to the top or bottom of a control structure.
FOR...NEXT loops
WHILE...NEXT loops
UNTIL...NEXT loops
IF...THEN...ELSE blocks
SELECT...CASE blocks
SUB, FUNCTION, and PICTURE subprograms
DEF functions, and programs
In the case of control structures, EXIT passes control to the first statement following the end of the control structure.
You can use ITERATE to explicitly reexecute a FOR...NEXT, WHILE...NEXT, or UNTIL...NEXT loop. EXIT and ITERATE statements can appear only within the code blocks you want to leave or reexecute.
Executing the ITERATE statement is equivalent to transferring control to the loop's NEXT statement. The termination test is still performed when the NEXT statement transfers control to the top of the loop. In addition, transferring control to the NEXT statement means that a FOR loop's control variable is incremented by the STEP value.
Supplying a label for every loop lets you state explicitly which loop to leave or reexecute. If you do not supply a label for the ITERATE statement, VSI BASIC for OpenVMS reexecutes the innermost active loop. For example, if an ITERATE statement (that does not specify a label) is executed in the innermost of three nested loops, only the innermost loop is reexecuted.
In contrast, labeling each loop and supplying a label argument to the ITERATE statement lets you reexecute any of the loops. A label name also helps document your code. Because you must use a label with EXIT and it is sometimes necessary to use a label with ITERATE, you should always label the structures you want to control with these statements.
DECLARE STRING User_string Read_loop: WHILE 1% = 1% LINPUT "Please type a string"; User_string IF User_string == "" THEN EXIT Read_loop ELSE PRINT "Length is ";LEN(User_string) ITERATE Read_loop END IF NEXT END
9.6. Executing Local Subroutines
In VSI BASIC for OpenVMS, a subroutine is a block of code accessed by a GOSUB or ON GOSUB statement. It must be in the same program unit as the statement that calls it. The RETURN statement in the subroutine returns control to the statement immediately following the GOSUB.
The first line of a subroutine can be any valid VSI BASIC for OpenVMS statement, including a REM statement. You do not have to transfer control to the first line of the subroutine. Instead, you can include several entry points into the same subroutine. You can also reference subroutines by using a GOSUB or ON GOSUB statement to another subroutine.
Variables and data in a subroutine are global to the program unit in which the subroutine resides.
9.6.1. GOSUB and RETURN Statements
The GOSUB statement unconditionally transfers control to a line in a subroutine. The last statement in a subroutine is a RETURN statement, which returns control to the first statement after the calling GOSUB. A subroutine can contain more than one RETURN statement so you can return control conditionally, depending on a specified condition.
A = 5 GOSUB Times_two PRINT A A = 15 GOSUB Times_two PRINT A A = 25 GOSUB Times_two PRINT A GOTO Done Times_two: !This is the subroutine entry point A = A * 2 RETURN Done: END
Output
10 30 50
Note that VSI BASIC for OpenVMS signals “RETURN without GOSUB” if it encounters a RETURN statement without first having encountered a GOSUB or ON GOSUB statement.
9.6.2. ON...GOSUB...OTHERWISE Statement
The ON...GOSUB...OTHERWISE statement transfers control to one of several target subroutines depending on the value of a numeric expression. A RETURN statement returns control to the first statement after the calling ON GOSUB. A subroutine can contain more than one RETURN statement so that you can return control conditionally, depending on a specified condition.
INPUT "Please enter first integer value"; First_value% INPUT "Please enter second integer value"; Second_value% Choice: PRINT "Do you want to perform:" PRINT "1. Multiplication" PRINT "2. Division" PRINT "3. Exponentiation" INPUT Selection% ON Selection% GOSUB Mult, Div, Expon OTHERWISE Wrong GOTO Done Mult: Result% = First_value% * Second_value% PRINT Result% RETURN Div: Result% = First_value / Second_value% PRINT Result% RETURN Expon: Result% = First_value% ** Second_value% PRINT Result% RETURN Wrong: PRINT "Invalid selection" RETURN Done: END
9.7. Suspending and Halting Program Execution
- SLEEP
- WAIT
These statements cause VSI BASIC for OpenVMS either to suspend program execution for a specified time or to wait a certain period of time for user input.
- STOP
- END
The STOP statement does not close files. It can appear anywhere in a program. The END statement closes files and must be the last statement in a main program.
9.7.1. SLEEP Statement
INPUT "Type a string of characters"; C$ SLEEP 120% PRINT C$ END
The SLEEP statement is useful if you have a program that depends on another program for data. Instead of constantly checking for a condition, the SLEEP statement lets you check the condition at specified intervals.
9.7.2. WAIT Statement
WAIT 30% INPUT "You have 30 seconds to type your password"; PSW$ END
The WAIT statement affects all subsequent INPUT, INPUT LINE, LINPUT, MAT INPUT, and MAT LINPUT statements. To disable a previously specified WAIT statement, use WAIT 0%.
WAIT 30% INPUT "You have 30 seconds to type your password"; PSW$ WAIT 0% INPUT "What directory do you want to go to"; DIR$
9.7.3. STOP Statement
The STOP statement is a debugging tool that lets you check the flow of program logic. STOP suspends program execution but does not close files.
When VSI BASIC for OpenVMS executes a STOP statement, it signals “STOP at line
<line-num>
.”
CONTINUE (to continue program execution)
EXIT (to return to DCL command level)
9.7.4. END Statement
The END statement marks the end of a main program. When VSI BASIC for OpenVMS executes an END statement, it closes all files and halts program execution.
The END statement is optional in VSI BASIC for OpenVMS programs. However, it is good programming practice to include it. The END statement must be the last statement in the main program.
The END statement returns you to DCL command level.
Chapter 10. Functions
A function is a single statement or group of statements that perform operations on operands and return the result to your program. VSI BASIC for OpenVMS has built-in functions that perform numeric and string operations, conversions, and date and time operations. This chapter describes only a selected group of built-in functions. For a complete description of all VSI BASIC for OpenVMS built-in functions, see the VSI BASIC Reference Manual.
With the DEF statement
As separately compiled subprograms (external functions)
DEF function definitions are local to a program module, while external functions can be accessed by any program module. You create local functions with the DEF statement and optionally declare them with the DECLARE statement. You create external functions with the FUNCTION statement and declare them with the EXTERNAL statement. For more information about creating external functions with the FUNCTION statement, see Chapter 12, Program Segmentation.
Once you create and declare a function, you can invoke it like a built-in function.
10.1. Built-In Functions
The functions described in this section let you perform sophisticated manipulations of string and numeric data. VSI BASIC for OpenVMS also provides algebraic, exponential, trigonometric, and randomizing mathematical functions.
10.1.1. Numeric Functions
Numeric functions generally return a result of the same data type as the function's parameter. For example, if you pass a DOUBLE argument to any of the trigonometric functions, they return a DOUBLE result.
If the format of a VSI BASIC for OpenVMS function specifies an argument of a particular data type, VSI BASIC for OpenVMS converts the actual argument supplied to the specified data type. For example, if you supply an integer argument to a function that expects a floating-point number, VSI BASIC for OpenVMS converts the argument to a floating-point number. Floating-point arguments that are passed to integer functions are truncated, not rounded.
The following sections discuss the VSI BASIC for OpenVMS built-in numeric functions.
10.1.1.1. ABS Function
READ A,B DATA 10,-35.3 NEW_A = ABS(A) PRINT NEW_A; ABS(B) END
Output
10 35.3
The ABS function always returns a number of the default floating-point data type.
10.1.1.2. INT and FIX Functions
The INT function returns the floating-point value of the largest integer less than or equal to a specified expression. The INT function always returns a number of the default floating-point type.
The FIX function truncates the value of a floating-point number at the decimal point. FIX always returns a number of the default floating-point type.
PRINT INT(23.553); FIX(23.553) PRINT INT(3.1); FIX(3.1) PRINT INT(-45.3); FIX(-45.3) PRINT INT(-11); FIX(-11) END
Output
23 23 3 3 -46 -45 -11 -11
10.1.1.3. SIN, COS, and TAN Functions
The SIN, COS, and TAN functions return the sine, cosine, and tangents of an angle in radians or degrees, depending on which angle clause you choose with the OPTION statement. If you supply a floating-point argument to the SIN, COS, and TAN functions, they return a number of the same floating-point type. If you supply an integer argument, they convert the argument to the default floating-point data type and return a floating-point number of that type.
!CONVERT ANGLE (X) TO RADIANS, AND !FIND SIN, COS AND TAN PRINT "DEGREES", "RADIANS", "SINE", "COSINE","TANGENT" FOR I% = 0% TO 5% READ X LET Y = X * 2 * PI / 360 PRINT PRINT X ,Y ,SIN(Y) ,COS(Y) ,TAN(Y) NEXT I% DATA 0,10,20,30,360,45 END
Output
DEGREES RADIANS SINE COSINE TANGENT 0 0 0 1 0 10 .174533 .173648 .984808 .176327 20 .349066 .34202 .939693 .36397 30 .523599 .5 .866025 .57735 360 6.28319 .174846E-06 1 .174846E-06 45 .785398 .707107 .707107 1
Note
As an angle approaches 90 degrees (PI/2 radians), 270 degrees (3*PI/2 radians), 450 degrees (5*PI/2 radians), and so on, the tangent of that angle approaches infinity. If your program tries to find the tangent of such an angle, VSI BASIC for OpenVMS signals “Division by 0” (ERR=61).
10.1.1.4. SQR Function
PRINT SQR (2)
Output
1.41421
10.1.1.5. LOG10 Function
A logarithm is the exponent of some number (called a base). Common logarithms use the base 10. The common logarithm of a number n, for example, is the power to which 10 must be raised to equal n. For example, the common logarithm of 100 is 2, because 10 raised to the power 2 equals 100.
FOR I% = 10% TO 100% STEP 10% PRINT LOG10(I%) NEXT I% END
Output
1 1.30103 1.47712 1.60206 1.69897 1.77815 1.8451 1.90309 1.95424 2
If you supply a floating-point argument to LOG10, the function returns a floating-point number of the same data type. If you supply an integer argument, LOG10 converts it to the default floating-point data type and returns a value of that type.
10.1.1.6. EXP Function
READ A,B DATA 1,2 PRINT 'e RAISED TO THE POWER'; A; " EQUALS"; EXP(A) PRINT 'e RAISED TO THE POWER'; B; " EQUALS"; EXP(B) END
Output
e RAISED TO THE POWER 1 EQUALS 2.71828 e RAISED TO THE POWER 2 EQUALS 7.38906
If you supply a floating-point argument to EXP, the function returns a floating-point number of the same data type. If you supply an integer argument, EXP converts it to the default floating-point data type and returns a value of that type.
10.1.1.7. RND Function
PRINT RND,RND,RND,RND END
Output 1
.76308 .179978 .902878 .88984
Output 2
.76308 .179978 .902878 .88984
RANDOMIZE PRINT RND,RND,RND,RND END
Output 1
.403732 .34971 .15302 .92462
Output 2
.404165 .272398 .261667 .10209
(B-A)*RND + A
FOR I% = 1% TO 10% PRINT (6%-4%) * RND + 4 NEXT I% END
Output
5.52616 4.35996 5.80576 5.77968 4.77402 4.95189 5.76439 4.37156 5.2776 4.53843
10.1.2. Data Conversion Functions
Convert a 1-character string to the character's ASCII value and vice versa
Translate strings from one data format to another, for example, EBCDIC to ASCII
The following sections describe some of these functions.
10.1.2.1. ASCII Function
test_string$ = "BAT" PRINT ASCII(test_string$) END
Output
66
Note that the ASCII value of a null string is zero.
10.1.2.2. CHR$ Function
The CHR$ function returns the character whose ASCII value you supply. If the ASCII integer expression that you supply is less than zero or greater than 255, VSI BASIC for OpenVMS treats it as a modulo 256 value. VSI BASIC for OpenVMS treats the integer expression as the remainder of the actual supplied integer divided by 256. Therefore, CHR$(325) is equivalent to CHR$(69) and CHR$(-1) is equivalent to CHR$(255).
PRINT "THIS PROGRAM FINDS THE CHARACTER WHOSE" PRINT "VALUE (MODULO 256) YOU TYPE" INPUT value% PRINT CHR$(value%) END
Output 1
THIS PROGRAM FINDS THE CHARACTER WHOSE VALUE (MODULO 256) YOU TYPE ? 69 E
Output 2
THIS PROGRAM FINDS THE CHARACTER WHOSE VALUE (MODULO 256) YOU TYPE ? 1093 E
10.1.3. String Numeric Functions
Numeric strings are numbers represented by ASCII characters. A numeric string consists of an optional sign, a string of digits, and an optional decimal point. You can use E notation in a numeric string for floating-point constants.
The following sections describe some of the VSI BASIC for OpenVMS numeric string functions.
10.1.3.1. FORMAT$ Function
A = 5 B$ = "##.##" Z$ = FORMAT$(A, B$) PRINT Z$ END
Output
5.00
10.1.3.2. NUM$ and NUM1$ Functions
PRINT NUM$(7465097802134) PRINT NUM$(-50) END
Output
.74651E+13 -50
PRINT NUM1$(PI) PRINT NUM1$(97.5 * 30456.23 + 30385.1) PRINT NUM1$(1E-38) END
Output
3.14159 2999870 .00000000000000000000000000000000000001
NUM1$ returns up to 6 digits of accuracy for SINGLE and SFLOAT real numbers, up to 16 digits of accuracy for DOUBLE numbers, up to 10 digits of accuracy for LONG integers, and up to 19 digits of accuracy for QUAD integers. NUM1$ returns up to 15 digits of accuracy for GFLOAT and TFLOAT numbers and up to 33 digits of accuracy for XFLOAT numbers.
A$ = NUM$(1000000) B$ = NUM1$(1000000) PRINT LEN(A$); "/"; A$; "/" PRINT LEN(B$); "/"; B$; "/" END
Output
8 / .1E+07 / 7 /1000000/
Note that A$ has a leading and trailing space.
10.1.3.3. VAL% and VAL Functions
The VAL% function returns the integer value of a numeric string. This numeric string expression must be the string representation of an integer. It can contain the ASCII characters 0 to 9, a plus sign (+), or a minus sign (-).
The VAL function returns the floating-point value of a numeric string. The numeric string expression must be the string representation of some number. It can contain the ASCII characters 0 to 9, a plus sign (+), a minus sign (-), or an uppercase E.
The VAL function returns a number of the default floating-point data type. VSI BASIC for OpenVMS signals “Illegal number” (ERR=52) if the argument is outside the range of the default floating-point data type.
A = VAL("922") B$ = "100" C% = VAL%(B$) PRINT A PRINT C% END
Output
922 100
10.1.4. String Arithmetic Functions
In BASIC, string arithmetic functions process numeric strings as arithmetic operands. This lets you add (SUM$), subtract (DIF$), multiply (PROD$), and divide (QUO$) numeric strings, and express them at a specified level of precision (PLACE$).
String arithmetic offers greater precision than floating-point arithmetic or longword integers and eliminates the need for scaling. However, string arithmetic executes more slowly than the corresponding integer or floating-point operations.
Function |
Format |
Description |
---|---|---|
SUM$ |
SUM$(A$,B$) |
B$ is added to A$. |
DIF$ |
DIF$(A$,B$) |
B$ is subtracted from A$. |
PROD$ |
PROD$(A$,B$,P%) |
A$ is multiplied by B$. The product is expressed with precision P%. |
QUO$ |
QUO$(A$,B$,P%) |
A$ is divided by B$. The quotient is expressed with precision P%. |
PLACE$ |
PLACE$(A$,P%) |
A$ is expressed with precision P%. |
Function |
How Determined |
How Stated |
---|---|---|
SUM$ |
Precision of argument |
Implicitly |
DIF$ |
Precision of argument |
Implicitly |
PROD$ |
Value of argument |
Explicitly |
QUO$ |
Value of argument |
Explicitly |
PLACE$ |
Value of argument |
Explicitly |
10.1.4.1. SUM$ and DIF$ Functions
The SUM$ and DIF$ functions take the precision of the more precise argument in the function unless padded zeros generate that precision. SUM$ and DIF$ omit trailing zeros to the right of the decimal point.
The sum or difference of two integers takes the precision of the larger integer.
The sum or difference of two decimal fractions takes the precision of the more precise fraction.
- The sum or difference of two real numbers takes precision as follows:
The sum or difference of the integer parts takes the precision of the larger part.
The sum or difference of the decimal fraction parts takes the precision of the more precise part.
Trailing zeros are trunctated.
10.1.4.2. QUO$, PLACE$, and PROD$ Functions
In the QUO$, PLACE$, and PROD$ functions, the value of the integer expression argument explicitly determines numeric precision. That is, the integer expression parameter determines the point at which the number is rounded or truncated.
For positive integer expressions, rounding occurs to the right of the decimal point. For example, if the integer expression is 1, rounding occurs one digit to the right of the decimal point (the number is rounded to the nearest tenth). If the integer expression is 2, rounding occurs two digits to the right of the decimal point (the number is rounded to the nearest hundredth), and so on.
For zero, rounding occurs to the nearest unit.
For negative integer expressions, rounding occurs to the left of the decimal point. For example, if the integer expression is -1, rounding occurs one place to the left of the decimal point. In this case, VSI BASIC for OpenVMS moves the decimal point one place to the left, then rounds to units. If the integer expression is -2, rounding occurs two places to the left of the decimal point; VSI BASIC for OpenVMS moves the decimal point two places to the left, then rounds to units.
Note that when rounding numeric strings, VSI BASIC for OpenVMS returns only part of the number.
If the integer expression is 10,000, VSI BASIC for OpenVMS truncates the number at the decimal point.
If the integer expression is greater than 10,000 (10,000 plus n), VSI BASIC for OpenVMS truncates the numeric string n places to the right of the decimal point. For example, if the integer expression is 10,001 (10,000 plus 1), VSI BASIC for OpenVMS truncates the number starting one place to the right of the decimal point. If the integer expression is 10,002 (10,000 plus 2), VSI BASIC for OpenVMS truncates the number starting two places to the right of the decimal point, and so on.
If the integer expression is less than 10,000 (10,000 minus n) VSI BASIC for OpenVMS truncates the numeric string n places to the left of the decimal point. For example, if the integer expression is 9999 (10,000 minus 1), VSI BASIC for OpenVMS truncates the number starting one place to the left of the decimal point. If the integer expression is 9998 (10,000 minus 2), VSI BASIC for OpenVMS truncates starting two places to the left of the decimal point, and so on.
The PLACE$ function returns a numeric string, truncated or rounded according to an integer argument you supply.
number$ = "123456.654321" FOR I% = -5% TO 5% PRINT PLACE$(number$, I%) NEXT I% PRINT FOR I% = 9995 TO 10005 PRINT PLACE$(number$, I%) NEXT I%
Output
1 12 123 1235 12346 123457 123456.7 123456.65 123456.654 123456.6543 123456.65432 1 12 123 1234 12345 123456 123456.6 123456.65 123456.654 123456.6543 123456.65432
A$ = "-4.333" B$ = "7.23326" s_product$ = PROD$(A$, B$, 10005%) PRINT s_product$ END
Output
-31.34171
10.1.5. Date and Time Functions
VSI BASIC for OpenVMS supplies functions to return the date and time in numeric or string format. The following sections discuss these functions.
Note that you can also use certain system services and Run-Time Library routines for more sophisticated date and time functions. See the VSI OpenVMS System Services Reference Manual and the VMS Run-Time Library Routines Volume for more information.
10.1.5.1. DATE$ Function
PRINT DATE$(0) PRINT DATE$(126) PRINT DATE$(6168) END
Output
15-Jun-85 06-May-70 16-Jun-76
If you supply an invalid date (for example, day 370 of the year 1973), the results are undefined.
See Section 10.1.5.2, “DATE4$ Function” for the recommended replacement for DATE$, which has a two-digit year field in the result string.
10.1.5.2. DATE4$ Function
PRINT 32150, DATE$ (32150), DATE4$ (32150)
32150 30-May-02 30-May-2002
See the description of the DATE$ function for more information.
10.1.5.3. TIME$ Function
PRINT TIME$(0) PRINT TIME$(1) PRINT TIME$(1440) PRINT TIME$(721) END
Output
03:53 PM 11:59 PM 12:00 AM 11:59 AM
10.1.5.4. TIME Function
Value |
Information Returned |
---|---|
0 |
Returns the number of seconds elapsed since midnight |
1 |
Returns the current job's CPU time in tenths of a second |
2 |
Returns the current job's connect time in minutes |
3 |
Returns zero |
4 |
Returns zero |
All other arguments to TIME are undefined and cause VSI BASIC for OpenVMS to signal “Not implemented” (ERR=250).
10.1.6. Terminal Control Functions
Enable and disable Ctrl/C trapping
Enable and disable terminal echoing
Read a single keystroke from a terminal
10.1.6.1. CTRLC and RCTRLC Functions
The CTRLC function enables Ctrl/C trapping, and the RCTRLC function disables Ctrl/C trapping. When Ctrl/C trapping is enabled, control is transferred to the program's error handler when Ctrl/C is detected at the controlling terminal.
Ctrl/C trapping is asynchronous. The trap can occur in the middle of an executing statement, and a statement so interrupted leaves variables in an undefined state. For example, the statement A$ = “ABC”, if interrupted by Ctrl/C, could leave the variable A$ partially set to “ABC” and partially left with its previous contents.
WHEN ERROR USE error_handler Y% = CTRLC . . . END WHEN HANDLER error_handler IF ERR = 28 THEN PRINT #1%, "Abort" . . . END HANDLER
Note
When you trap Ctrl/C with an error handler, your program might be in an inconsistent state; therefore, you should handle the Ctrl/C error and exit the program as quickly as possible.
10.1.6.2. ECHO and NOECHO Functions
The NOECHO function disables echoing on a specified channel. Echoing is the process by which characters typed at the terminal keyboard appear on the screen.
If you specify channel #0 (your terminal) as the argument, the characters typed on the keyboard are still accepted as input; however, they do not appear on the screen.
The ECHO function enables echoing on a specified channel and cancels the effect of the NOECHO function on that channel.
Y% = NOECHO(0%) INPUT "PASSWORD"; pword$ IF pword$=="PLUGH" THEN PRINT "THAT IS CORRECT" END IF Y% = ECHO(0%) END
Note that the Y% = ECHO(0%) statement is necessary to turn the echo back on. If this statement were not included, then all subsequent user inputs would not echo to the terminal screen.
10.1.6.3. INKEY$ Function
The INKEY$ function reads a single keystroke from a terminal opened on a specified channel and returns the typed character.
If you specify a channel that is not open, VSI BASIC for OpenVMS signals the error “I/O channel not open” (ERR=9). If a file or a device other than a terminal is open on the channel, VSI BASIC for OpenVMS signals the error “Illegal operation” (ERR=141).
DECLARE STRING KEYSTROKE Inkey_Loop: WHILE 1% KEYSTROKE = INKEY$(1%,WAIT) SELECT KEYSTROKE CASE '26'C PRINT "Ctrl/Z to exit" EXIT Inkey_Loop CASE CR,LF,VT,FF,ESC PRINT "Line terminator" CASE "PF1" TO "PF4" PRINT "P key" CASE "E1" TO "E6" PRINT "VT200 Function key" CASE "KP0" TO "KP9" PRINT "Application keypad key" CASE < SP PRINT "Control character" CASE '127'C PRINT "<DEL>" CASE ELSE PRINT "Character is "; KEYSTROKE END SELECT NEXT
10.2. User-Defined Functions
The DEF statement lets you create your own single-line or multiline functions.
The letters FN
From 1 to 28 letters, digits, underscores, or periods
An optional percent sign or dollar sign
Integer function names must end with a percent sign (%), and string function names must end with a dollar sign ($); therefore, the function name can have up to 31 characters. If the function name ends with neither a percent sign nor a dollar sign, the function returns a real number.
You can create user-defined functions using these function naming rules; however, it is recommended that you use explicit data typing when defining functions for new program development. See Chapter 12, Program Segmentation for an example of an explicitly declared function. Note that the function name must start with FN only if the function is not explicitly declared, and a function reference lexically precedes the function definition.
DEF functions can be either single-line or multiline. Whether you use the single-line or multiline format for function definitions depends on the complexity of the function you create. In general, multiline DEF functions perform more complex functions than single-line DEF functions and are suitable for recursive operations.
If you want to pass values to a function, the function definition requires a formal parameter list. These formal parameters are the variables used to calculate the value returned by the function. When you invoke a function, you supply an actual parameter list; the values in the actual parameter list are copied into the formal parameter at this time. DEF functions allow up to 255 formal parameters. You can specify variables, constants, or array elements as formal parameters, but you cannot specify an entire array as a parameter to a DEF function.
10.2.1. Single-Line DEF Functions
In a single-line DEF, the function name, the formal parameter list, and the defining expression all appear on the same line. The defining expression specifies the calculations that the function performs. You can pass up to 255 arguments to this function through the formal parameter list. These parameters are variables local to the function definition, and each formal parameter can be preceded by a data type keyword.
The following example creates a function named fnratio. This function has two formal parameters: numer and denomin, whose ratio is returned as a REAL value.
Copies the values 5.6 and 7.8 into the formal parameters numer and denomin
Evaluates the expression to the right of the equal sign
Returns the value to the statement that invoked the function (the PRINT statement)
DEF REAL fnratio (numer, denomin) = numer / denomin PRINT fnratio(5.6, 7.8) END
Output
.717949
Note that the actual parameters you supply must agree in number and data type with those in the formal parameter list; you must supply numeric values for numeric variables, and string values for string variables.
DEF FN_A(X) = X^2 + 3 * X + 4 DEF FN_B(X) = FN_A(X) / 2 + FN_A(X) DEF FN_C(X) = SQR(X+4) + 1 DEF CUBE(X) = X ^ 3
Note that the name of the last function defined does not begin with FN. This is valid as long as no reference to the function lexically precedes the function definition.
DATE$ (0) returns a date string in the form dd-Mmm-yy.
The SEG$ function strips out of this value the characters starting at character position 1 up to and including the character at position 2 (the day number).
The VAL% function converts this resulting numeric string to an integer. In this way, fnday_number returns the day of the month as an integer.
DEF INTEGER fnday_number = VAL% (SEG$(DATE$(0%), 1%, 2%))
10.2.2. Multiline DEF Functions
Note
If a multiline DEF function contains DATA statements, they are global to the program unit.
Multiline function definitions can contain any constant, variable, VSI BASIC for OpenVMS built-in function, or user-defined function. In VSI BASIC for OpenVMS, the function definition can contain a reference to the function you are defining. Therefore, a multiline DEF function can be recursive, or invoke itself; however, VSI BASIC for OpenVMS does not detect infinitely recursive DEF functions during compilation. If your program invokes an infinitely recursive DEF function, VSI BASIC for OpenVMS will eventually signal a fatal run-time error, typically the error “Access violation.”
You can use either the END DEF or EXIT DEF statements to exit from a user-defined function. The EXIT DEF statement is equivalent to an unconditional transfer to the END DEF statement.
DEF fn_discount(A) IF A > 10 THEN PRINT "OUT OF RANGE" EXIT DEF ELSE fn_discount = A^A END IF END DEF INPUT Z PRINT fn_discount(Z) END
Output 1
? 4 256
Output 2
? 12 OUT OF RANGE 0
DECLARE STRING FUNCTION concat (STRING, STRING) !Declare the function . . . DEF STRING concat (STRING Y, STRING Z) concat = Y + Z !Define the function FNEND . . . new_string$ = concat(A$, B$) !Invoke the function . . . END
DECLARE REAL FUNCTION mdlo (REAL, INTEGER) DEF mdlo( REAL argument, INTEGER modulus ) !Check for argument equal to zero EXIT DEF IF argument = 0 !Check for modulus equal to zero, modulus equal to absolute !value of argument, and modulus greater than absolute !value of argument. SELECT modulus CASE = 0% EXIT DEF CASE > ABS( argument ) EXIT DEF CASE = ABS( argument ) mdlo = argument EXIT DEF END SELECT !If argument is negative, set flag negative% and set argument !to its absolute value. IF argument < 0 THEN argument = ABS( argument ) negative% = -1% END IF UNTIL argument < modulus argument = argument - modulus !If this calculation ever results in zero, mdlo returns zero IF argument = modulus THEN mdlo = 0 EXIT DEF END IF NEXT !Argument now contains the right number, but the sign might be wrong. !If the negative argument flag was set, make the result negative. IF negative% THEN mdlo = - argument ELSE mdlo = argument END IF END DEF INPUT "PLEASE INPUT THE VALUE AND THE MODULUS"; X,Y PRINT mdlo(X,Y) END
Output
PLEASE INPUT THE VALUE AND THE MODULUS? 7, 5 2
Because these functions are declared in DECLARE statements, the function names do not have to conform to the traditional VSI BASIC for OpenVMS rules for naming functions.
DECLARE INTEGER FUNCTION factor ( INTEGER ) DEF INTEGER factor ( INTEGER F ) IF F <= 0% THEN factor = 1% ELSE factor = factor(F - 1%) * F END IF END DEF INPUT "INPUT N TO FIND N FACTORIAL"; N% PRINT "N! IS"; factor(N%) END
Output
INPUT N TO FIND N FACTORIAL? 5 N! IS 120
Any variable accessed or declared in the DEF function and not in the formal parameter list is global to the program unit. When VSI BASIC for OpenVMS evaluates the user-defined function, these global variables contain the values last assigned to them in the surrounding program module.
To prevent confusion, variables declared in the formal parameter list should not appear elsewhere in the program. Note that if your function definition actually uses global variables, these variables cannot appear in the formal parameter list.
If the DEF function contains an ON ERROR GOTO, GOTO, ON GOTO, GOSUB, ON GOSUB, or RESUME statement, that statement's target line number must also be in that DEF function.
An ON ERROR GO BACK statement can transfer control out of a DEF function; however, a RESUME statement in an error handler outside the DEF function cannot transfer control back into the DEF function.
If the DEF function contains a handler, and was invoked from a protected region, an EXIT HANDLER statement causes control to be transferred to the specified handler for that protected region. However, if the DEF function contains a handler but was not invoked from a protected region, an EXIT HANDLER statement causes control to be transferred to the default error handler.
A subroutine cannot be shared by more than one DEF function; however, if you rewrite the subroutine as a DEF function with no parameters, other function definitions can share it.
A DEF function never changes the value of a parameter passed to it. Also, because formal parameters are local to the function definition, you cannot access the values of these variables from outside the DEF statement. These variable names are known only inside the DEF statement.
OPTION TYPE = EXPLICIT DECLARE INTEGER A, B DEF fn_sum(INTEGER first, INTEGER second) = first + second A = 50 B = 25 PRINT fn_sum(A, B) PRINT first END
Chapter 11. String Handling
This chapter defines dynamic and fixed-length strings and string virtual arrays, explains which you should choose for your application, and shows you how to use them.
11.1. Overview of Strings
Dynamic strings
Fixed-length strings
String virtual arrays
Dynamic strings are strings whose length can change during program execution. The length of a dynamic string variable can change or not, depending on the statement used to modify it.
Fixed-length strings are strings whose length never changes. In other words, their length remains static. String constants are always fixed-length. String variables can be either fixed-length or dynamic. A string variable is fixed-length if it is named in a COMMON, MAP, or RECORD statement. If a string variable is not part of a map or common block, RECORD, or virtual array, it is a dynamic string. When a string variable is fixed-length, its length does not change, regardless of the statement you use to modify it. Table 11.1, “String Modification” provides more information about string modification.
Statement |
Changes Made to Fixed-Length Strings |
Changes Made to Dynamic Strings |
---|---|---|
LET |
Value |
Value and length |
LSET |
Value |
Value |
RSET |
Value |
Value |
Terminal I/O Statements ? |
Value |
Value and length |
11.2. Using Dynamic Strings
Although dynamic strings are less efficient than fixed-length strings, they are often more flexible. For example, to concatenate strings, you can use the LET statement to assign the concatenated value to a dynamic string variable, without having to be concerned about VSI BASIC for OpenVMS truncating the string or adding trailing spaces to it. However, if the destination variable is fixed-length, you must make sure that it is long enough to receive the concatenated string, or VSI BASIC for OpenVMS truncates the new value to fit the destination string. Similarly, if you use LSET or RSET to concatenate strings, you must ensure that the destination variable is long enough to receive the data.
The LET, LSET, and RSET statements all operate on dynamic strings as well as fixed-length strings. The LET statement can change the length of a dynamic string; LSET and RSET do not. LSET and RSET are more efficient than LET when changing the value of a dynamic string. For more information about LSET and RSET, see Section 11.5.2, “LSET Statement” and Section 11.5.3, “RSET Statement”.
LET A$ = "ABC" LET B$ = "XYZ" LET C$ = " " LSET A$ = A$ + B$ LSET C$ = A$ + B$ PRINT A$ PRINT C$ END
Output
ABC ABCXYZ
Like the LET statement, the INPUT, INPUT LINE, and LINPUT statements can change the length of a dynamic string, but they cannot change the length of a fixed-length string.
!Declare a dynamic string LET A$ = "" PRINT LEN(A$) INPUT A$ PRINT A$ PRINT LEN(A$) END
Output
0 ? THIS IS A TEST THIS IS A TEST 14
You should not confuse the null string with a null character. A null character is one whose ASCII numeric code is zero. The null string is a string whose length is zero.
11.3. Using Fixed-Length Strings
It is generally more efficient to manipulate a fixed-length string than a dynamic string. Creating or modifying a dynamic string often causes VSI BASIC to create new storage, and this increases processor overhead.
MAP (FIELDS) STRING full_name = 10, & address = 10, & city_state = 10, & zip = 10 LINPUT "NAME"; full_name LINPUT "ADDRESS"; address LINPUT "CITY AND STATE"; city_state LINPUT "ZIP CODE"; zip EMPLOYEE_RECORD$ = full_name + HT + address + HT & + city_state + HT + zip PRINT EMPLOYEE_RECORD$ END
Output
NAME? JOE SMITH ADDRESS? 66 GRANT AVENUE CITY AND STATE? NEW YORK NY ZIP? 01001 JOE SMITH 66 GRANT A NEW YORK N 01001
11.4. Using String Virtual Arrays
Virtual arrays are stored on disk. You create a virtual array by opening a disk file and then using the DIM # statement to dimension the array on the open channel. This section describes only string virtual arrays. See Chapter 13, File Input and Output for more information about virtual arrays.
When you create the virtual string array, you specify a maximum length for the array's elements. The length of an array element can never exceed this maximum. If you do not supply a length, the default is 16 characters.
A string virtual array element cannot contain trailing nulls.
When you assign a value to a string virtual array element, VSI BASIC for OpenVMS pads the value with nulls, if necessary, to fit the length of the virtual array element; however, when you retrieve the virtual array element, VSI BASIC for OpenVMS strips all trailing nulls from the string. Therefore, when you access an element in a string virtual array, the string never has trailing nulls.
DIM #1%, STRING test(5) OPEN "TEST" AS FILE #1%, ORGANIZATION VIRTUAL A$, test(1%) = "ABCDE" + STRING$(5%, 0%) PRINT "LENGTH OF A$ IS: "; LEN(A$) PRINT "LENGTH OF TEST(1) IS: "; LEN(test(1%)) END
Output
LENGTH OF A$ IS: 10 LENGTH OF TEST(1) IS: 5
Although the storage for string virtual array elements is fixed, the length of a string array element can change because VSI BASIC for OpenVMS strips the trailing nulls whenever it retrieves a value from the array.
11.5. Assigning String Data
To assign string data, you use the LET, LSET, RSET, and MID$ statements. The following sections describe how to use these statements.
11.5.1. LET Statement
LET B = "ret_status"
MAP (TEST) STRING ABC = 10 DECLARE STRING XYZ ABC = "ABC" XYZ = "XYZ" PRINT ABC, LEN(ABC) PRINT XYZ, LEN(XYZ) ABC = "A" XYZ = "X" PRINT ABC, LEN(ABC) PRINT XYZ, LEN(XYZ)
Output
ABC 10 XYZ 3 A 10 X 1
11.5.2. LSET Statement
LSET ABC = "ABC"
LET test$ = "ABCDE" LSET test$ = "XYZ" PRINT "'"; test$; "'" END
Output
'XYZ '
LET test$ = "ABCDE" LSET test$ = "12345678" PRINT test$ END
Output
12345
The LET statement creates the 5-character string variable test$. The LSET statement in the second line assigns the characters “12345” to test$. Because LSET does not change the string variable's length, it truncates the last three characters (678).
11.5.3. RSET Statement
RSET C_R = "cust_rec"
LET test$ = "ABCDE" RSET test$ = "XYZ" PRINT "'" ; test$; "'" END
Output
' XYZ'
LET test$ = "ABCDE" RSET test$ = "987654321" PRINT test$ END
Output
54321
The LET statement creates a 5-character string variable, test$. The RSET statement assigns “54321” to test$. RSET, which does not change the variable's length, truncates “9876” from the left side of the string expression.
LET A$ = '12345' LSET A$ = 'ABC' LET B$ = '12345678' RSET B$ = A$ PRINT "'";B$;"'"
Output
' ABC '
11.5.4. MID$ Assignment Statement
You can replace a portion of a string with another string using the MID$ assignment statement. You specify a starting character position that indicates where to begin the substitution. If you specify a starting character position that is less than 1, VSI BASIC for OpenVMS assumes a starting character position of 1. In addition, you can optionally specify the number of characters to substitute from the source string expression. If you do not specify the number of characters to substitute, VSI BASIC for OpenVMS attempts to insert the entire source expression. However, the MID$ statement never changes the length of the target string variable; therefore, the entire source expression might not fit into the available space.
DECLARE STRING old_string, replace_string old_string = "ABCD" replace_string = "123" PRINT old_string MID$(old_string,1,3) = replace_string PRINT old_string
Output
ABCD 123D
The length argument is optional. If not specified, the number of characters replaced will be the minimum of the length of the replacement string and the length of the input string minus the starting position value.
If the length of the segment is less than or equal to zero, VSI BASIC for OpenVMS assumes a length of zero.
The length of the input string does not change regardless of the value of the length of the segment.
11.6. Manipulating String Data with String Functions
Determine the length of a string (LEN)
Search for the position of a set of characters in a string (POS)
Extract segments from a string (SEG$, MID$)
Create a string of any length, made up of any single character (STRING$)
Create a string of spaces (SPACE$)
Remove trailing spaces and tabs from a string (TRM$)
Edit a string (EDIT$)
These functions are discussed in the following sections. See the VSI BASIC Reference Manual for more information about each string's function.
11.6.1. LEN Function
LEN(spec)
"ABC XYZ",
, which has a length of
eight:alpha$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" PRINT LEN(alpha$) Z$ = "ABC" + " " + ""XYZ" PRINT LEN(Z$) END
Output
26 8
11.6.2. POS Function
POS(spec,test,15)
The position returned by POS is relative to the beginning of the string, not the starting position of the search. For example, if you search the string “ABCDE” for the substring “E”, it does not matter whether you specify a starting position of 1, 2, 3, 4, or 5, VSI BASIC for OpenVMS still returns the value 5 as the position where the substring was found.
alpha$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" Z$ = "DEFG" X% = POS(ALPHA$,Z$,1%) PRINT X% Q$ = "TEST" Y% = POS(ALPHA$, Q$, 1%) PRINT Y% END
Output
4 0
alpha$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" Z$ = "HIJ" PRINT POS(ALPHA$, Z$, 7%) END
Output
8
If you know that the substring is not near the string's beginning, specifying a starting position greater than one speeds program execution by reducing the number of characters VSI BASIC for OpenVMS must search.
DECLARE STRING CONSTANT table = & "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC" DECLARE STRING month, UPPER_CASE_MONTH, message DECLARE INTEGER month_length DECLARE REAL month_pos PRINT "Please type the first three letters of a month" PRINT "To end the program, type only Return"; Loop_1: WHILE 1% = 1% INPUT month UPPER_CASE_MONTH = EDIT$(month, 32%) month_length = LEN(UPPER_CASE_MONTH) EXIT Loop_1 IF month_length = 0% IF month_length = 3% THEN month_pos = (POS(table, UPPER_CASE_MONTH, 1) + 2) / 3 IF (month_pos = 0%) OR (month_pos <> FIX(month_pos)) THEN MESSAGE = " Invalid abbreviation, try again" ELSE MESSAGE = " is month number" + NUM$(MONTH_POS) END IF ELSE MESSAGE = " Abbreviation not three characters, try again" END IF PRINT month; message NEXT END
Output
Please type the first three letters of a month To end the program, type only Return? Nov Nov is month number 11
If you specify a starting position less than 1, POS assumes a starting position of one.
If you specify a starting position greater than the searched string's length, POS returns a zero (unless the substring is null).
- When searching for a null string:
If you specify a starting position greater than the string's length, POS returns the string's length plus one.
If the string to be searched is also null, POS returns a value of one.
If the specified starting position is less than or equal to 1, POS returns a value of one.
If the specified starting position is greater than one and less than or equal to the string's length plus 1, POS returns the specified starting position.
Note that searching for a null string is not the same as searching for the null character. A null string has a length of zero, while the null character has a length of one. The null character is an ASCII character whose value is zero.
11.6.3. SEG$ Function
SEG$(time,13,16)
PRINT SEG$("ABCDEFG", 3%, 5%) END
Output
CDE
If you specify character positions that exist in the string, the length of the returned substring always equals (int-exp2 – int-exp1 + 1).
If the starting character position is less than 1, VSI BASIC for OpenVMS assumes a value of 1.
If the starting character position is greater than the ending character position, or the length of the string, SEG$ returns a null string.
If the ending character position is greater than the length of the string, SEG$ returns all characters from the starting character position to the end of the string.
If the starting character position is equal to the ending character position, SEG$ returns the character at the starting position.
A$ = "ABCDEFG" C$ = SEG$(A$, 1%, 2%) + "XYZ" + SEG$(A$, 6%, 7%) PRINT C$ PRINT A$ END
Output
ABXYZFG ABCDEFG
C$ = SEG$(A$,1%,n-1) + B$ + SEG$(A$,m+1,LEN(A$))
A$ = "ABCDEFGHIJK" B$ = "123456" C$ = SEG$(A$,1%,5%) + B$ + SEG$(A$,10%,LEN(A$)) PRINT C$ PRINT A$ PRINT B$ END
Output
ABCDE123456JK ABCDEFGHIJK 123456
- To replace the first n characters of A$ with B$ use:
C$ = B$ + SEG$(A$,n+1,LEN(A$))
- To replace all but the first n characters of A$ with B$ use:
C$ = SEG$(A$,1,n) + B$
- To replace all but the last n characters of A$ with B$ use:
C$ = B$ + SEG$(A$,(LEN(A$)--n) + 1, LEN(A$))
- To replace the last n characters of A$ with B$ use:
C$ = SEG$(A$,1,LEN(A$)--n) + B$
- To insert B$ in A$ after the nth character in A$ use:
C$ = SEG$(A$,1,n) + B$ + SEG$(A$,n+1,LEN(A$))
11.6.4. MID$ Function
The MID$ function extracts a specified substring, beginning at a specified character position and ending at a specified length. If you specify a starting character position that is less than 1, VSI BASIC for OpenVMS automatically assumes a starting character position of 1.
DECLARE STRING old_string, new_string old_string = "ABCD" new_string = MID$(old_string, 0, 3) PRINT new_string
Output
ABC
If the position of the segment's first character is greater than the input string, MID$ returns a null string.
If the length of the segment is greater than the length of the input string, VSI BASIC for OpenVMS returns the string that begins at the specified starting character position and includes all characters remaining in the string.
If the length of the segment is less than or equal to zero, MID$ returns a null string.
If you specify a floating-point expression for the position of the segment's first character or for the length of the segment, VSI BASIC for OpenVMS truncates it to a long integer.
11.6.5. STRING$ Function
STRING$(23,30)
out$ = STRING$(10%, 65%) PRINT out$ END
Output
AAAAAAAAAA
If the length of the returned string is less than or equal to zero, STRING$ returns a null string.
If the length of the returned string is greater than 65535, VSI BASIC for OpenVMS signals an error.
11.6.6. SPACE$ Function
SPACE$(5)
A$ = "ABC" B$ = "XYZ" PRINT A$ + SPACE$(3%) + B$ END
Output
ABC XYZ
11.6.7. TRM$ Function
A$ = "ABCDE " B$ = "XYZ" first$ = A$ + B$ second$ = TRM$(A$) + B$ PRINT first$ PRINT second$ END
Output
ABCDE XYZ ABCDEXYZ
The TRM$ function is especially useful for extracting the nonblank characters from a fixed-length string (for example, a COMMON or MAP, or a parameter passed from a program written in another language).
11.6.8. EDIT$ Function
EDIT$(stu_rec,32)
Value of Expression |
Effect |
---|---|
1 |
Discards each character's parity bit (bit 7). Note that you should not use this value for characters in the DEC Multinational character set. |
2 |
Discards all spaces and tabs. |
4 |
Discards all carriage returns, line feeds, form feeds, deletes, escapes, and nulls. |
8 |
Discards leading spaces and tabs. |
16 |
Converts multiple spaces and tabs to a single space. |
32 |
Converts lowercase letters to uppercase. |
64 |
Converts left brackets ([) to left parentheses [(], and right brackets (]) to right parentheses [)]. |
128 |
Discards trailing spaces and tabs. (Same as TRM$ function.) |
256 |
Suppresses all editing for characters within quotation marks. If the string has only one quotation mark, VSI BASIC for OpenVMS suppresses all editing for the characters following the quotation mark. |
Discard leading spaces and tabs (value 8)
Convert lowercase letters to uppercase (value 32)
Discard trailing spaces and tabs (value 128)
LINPUT "PLEASE TYPE A STRING";input_string$ new_string$ = EDIT$(input_string$, 2% + 32% + 64%) PRINT new_string$ END
Output
PLEASE TYPE A STRING? 88 abc TAB[5,5]
88ABC(5,5)
11.7. Manipulating String Data with Multiple Maps
MAP (emprec) first_name$ = 10, & last_name$ = 20, & street_number$ = 6, & street$ = 15, & city$ = 20, & state$ = 2, & zip$ = 5, & wage_class$ = 2, & date_of_review$ = 8, & salary_ytd$ = 10, & tax_ytd$ = 10 MAP (emprec) full_name$ = 30, & address$ = 48, & salary_info$ = 30 MAP (emprec) employee_record$ = 108
READ EMPLOYEE_RECORD$ DATA "WILLIAM DAVIDSON 2241 MADISON BLVD " & "SCRANTON PA14225A912/10/78$13,325.77$925.31"
Because all the MAP statements in the previous example reference the same storage area (emprec), you can access parts of this area through the mapped variables as shown in the following examples:
Example 1
PRINT full_name$ PRINT wage_class$ PRINT salary_ytd$
Output 1
WILLIAM DAVIDSON A9 $13,325.77
Example 2
PRINT last_name$ PRINT tax_ytd$
Output 2
DAVIDSON $925.31
Loop_1: WHILE 1% = 1% INPUT "Changes? (please type YES or NO)"; CH$ EXIT Loop_1 IF CH$ = "NO" PRINT "1. FIRST NAME" PRINT "2. LAST NAME" PRINT "3. STREET NUMBER" PRINT "4. STREET" PRINT "5. CITY" PRINT "6. STATE" PRINT "7. ZIP" PRINT "8. WAGE CLASS" PRINT "9. DATE OF REVIEW" PRINT "10. SALARY YTD" PRINT "11. TAX YTD" INPUT "CHANGE NUMBER"; NUMBER% SELECT NUMBER% CASE 1% INPUT "FIRST NAME"; first_name$ CASE 2% INPUT "LAST NAME"; last_name$ CASE 3% INPUT "STREET NUMBER"; street_number$ CASE 4% INPUT "STREET"; street$ CASE 5% INPUT "CITY"; city$ CASE 6% INPUT "STATE"; state$ CASE 7% INPUT "ZIP CODE"; zip$ CASE 8% INPUT "WAGE CLASS"; wage_class$ CASE 9% INPUT "DATE OF REVIEW"; date_of_review$ CASE 10% INPUT "SALARY YTD"; salary_ytd$ CASE 11% INPUT "TAX YTD"; tax_ytd$ CASE ELSE PRINT "Invalid choice" END SELECT NEXT END
Output
Changes? (please type YES or NO)? YES 1. FIRST NAME 2. LAST NAME 3. STREET NUMBER 4. STREET 5. CITY 6. STATE 7. ZIP 8. WAGE CLASS 9. DATE OF REVIEW 10. SALARY YTD 11. TAX YTD CHANGE NUMBER? 10 SALARY YTD? 14,277.08 Changes? (please type YES or NO)? YES CHANGE NUMBER? 11 TAX YTD? 998.32 Changes? (please type YES or NO)? NO
See Chapter 7, Data Definition and the VSI BASIC Reference Manual for more information about the MAP statement.
Chapter 12. Program Segmentation
Declare VSI BASIC subprograms
Write VSI BASIC subprograms
Program segmentation is the process of dividing a program into small, manageable routines and modules. In a segmented or modular program, each routine or module usually performs only one logical function. You can, therefore, design and implement a modular program faster than a nonsegmented program. Program modularity also simplifies debugging and testing, as well as program maintenance and transportability.
Subprograms processed by the VSI BASIC compiler conform to the OpenVMS Procedure Calling Standard. This standard prescribes how arguments are passed, how values are returned, and how procedures receive and return control. Because VSI BASIC conforms to the OpenVMS Procedure Calling Standard, a VSI BASIC subprogram or main program can call or be called by any procedure written in a language that also conforms to this standard. For information about calling non-BASIC procedures, see Chapter 19, Using BASIC in the Common Language Environment.
12.1. VSI BASIC Subprograms
FUNCTION subprograms must be declared with an EXTERNAL statement in the calling program. Declaring SUB subprograms is optional.
FUNCTION subprograms return a value; SUB subprograms do not return a value.
All subprograms invoked by a VSI BASIC program must have unique names. A VSI BASIC program cannot have different subprograms with the same identifiers.
Subprograms can return a value to the calling program with parameters. You can use subprograms to separate routines that you commonly use. For example, you can use subprograms to perform file I/O operations, to sort data, or for table lookups.
You can also use subprograms to separate large programs into smaller, more manageable routines, or you can separate modules that are modified often. If all references to system-specific features are isolated, it is easier to transport the program to a different system. OpenVMS System Services and OpenVMS Run-Time Library routines are specific to OpenVMS systems; therefore, you should consider isolating references to them in subprograms. Chapter 19, Using BASIC in the Common Language Environment describes how to access Run-Time Library routines and system services from VSI BASIC.
Data is passed as a parameter from the CALL statement or function invocation to the subprogram—see Section 12.2, “Declaring Subprograms and Parameters” for more information.
Data is part of a MAP or COMMON block—see Chapter 6, Arrays for information about using MAP and COMMON statements.
Data is in a file—see Chapter 13, File Input and Output for more information about accessing data from a file.
All DATA statements are local to a subprogram. Each time you call a subprogram, VSI BASIC positions the data pointer at the beginning of the subprogram's data.
The data pointer in the main program is not affected by READ or RESTORE statements in the subprogram (in contrast with the RESTORE # statement, which resets record pointers to the first record in the file no matter where it is executed). Chapter 5, Simple Input and Output contains more information about the READ and RESTORE statements. For more information about the RESTORE # statement, see Chapter 13, File Input and Output.
12.1.1. SUB Subprograms
A SUB subprogram is a program module that can be separately compiled and that cannot return a value. A SUB subprogram is delimited by the SUB and END SUB statements. You may use the EXTERNAL statement to explicitly declare the SUB subprogram.
Marks the end of the SUB subprogram
Does not affect I/O operations or files
Releases the storage allocated to local variables
Returns control to the calling program
The EXIT SUB statement transfers control to the statement lexically following the statement that invoked the subprogram. It is equivalent to an unconditional branch to an END SUB statement.
SUB sort_out (INTEGER X, INTEGER Y) DECLARE INTEGER temp IF X > Y THEN temp = X X = Y Y = temp ELSE EXIT SUB END IF END SUB
12.1.2. FUNCTION Subprograms
A FUNCTION subprogram is a program module that returns a value and can be separately compiled. It must be delimited by the FUNCTION and END FUNCTION statements. You use the EXTERNAL statement to name and explicitly declare the data type of an external function.
Marks the end of a function subprogram
Does not affect I/O operations or files
Releases the storage allocated to local variables
Optionally specifies a return value for the function
Returns control to the calling program
The EXIT FUNCTION statement immediately returns program control to the statement that invoked the function and optionally returns the function's return value. It is equivalent to an unconditional transfer to the END FUNCTION statement.
You can specify an expression with both the END FUNCTION and EXIT FUNCTION statements, which is another way of returning a function value. This expression must match the function data type, and it supersedes any function assignment. For more information, see the VSI BASIC Reference Manual.
FUNCTION REAL Sphere_volume (REAL R) IF R <= 0 THEN Sphere_volume = 0.0 ELSE Sphere_volume = 4/3 * PI * R ** 3 END IF END FUNCTION
PROGRAM call_sphere EXTERNAL REAL FUNCTION SPHERE_VOLUME(REAL) PRINT SPHERE_VOLUME(5.925) END PROGRAM
Note that this module is compiled separately from the FUNCTION subprogram. You can link these modules together to run the program from DCL level.
12.2. Declaring Subprograms and Parameters
You declare a subprogram by naming it in an EXTERNAL statement in the calling program. You may also declare the data type of each parameter. If the subprogram is a function, the EXTERNAL statement also lets you specify the data type of the returned value.
EXTERNAL SUB my_sub (LONG, STRING) EXTERNAL GFLOAT FUNCTION my_func (GFLOAT, LONG, GFLOAT) EXTERNAL REAL FUNCTION determinant (LONG DIM(,))
Note that the parameter lists contain only data type and dimension information; they cannot contain any format or actual parameters. When the external procedure is invoked, VSI BASIC ensures that the actual parameter data type matches the data type specified in the EXTERNAL declaration. However, VSI BASIC does not check to make sure that the parameters declared in the EXTERNAL statement match those in the external routine. You must ensure that these parameters match.
Constants
Variables
Expressions
Functions
Array elements
Entire arrays (but not virtual arrays)
CALL SUB01(var1, var2) CALL SUB02(Po_num%, Vouch, 66.67, Cust_list(5), FNA(B%))
However, when passing an entire array, you must use a special format. You specify the array name followed by commas enclosed in parentheses. The number of commas must be the number of array dimensions minus one. For example, array_name() is a one-dimensional array, array_name(,) is a two-dimensional array, array_name(,,) is a three-dimensional array, and so on.
PROGRAM fill_array OPTION TYPE = EXPLICIT DECLARE LONG I,J,K, three_d(10,10,10) EXTERNAL SUB example_sub (LONG DIM(,,)) FOR I = 0 TO 10 FOR J = 0 TO 10 FOR K = 0 TO 10 three_d(I,J,K) = I + J + K NEXT K NEXT J NEXT I CALL example_sub( three_d(,,)) END PROGRAM SUB example_sub( LONG X( , , )) . . . END SUB
The last specified parameter data type
An OPTION statement
A VSI BASIC compilation qualifier (for example, /REAL_SIZE=DOUBLE)
The system default
The last specified parameter data type overrides all the other default data types, the defaults specified in the OPTION statement override any compilation qualifiers and system defaults, and so on. When you know the length of a string or the dimensions of an array at compile time, you can achieve optimum performance by passing them BY REF. When you call programs written in other languages, the practice of declaring subprograms and specifying the data types of parameters becomes more important because other languages might not use the VSI BASIC default parameter-passing mechanisms. For more information about calling subprograms written in other languages, see Chapter 19, Using BASIC in the Common Language Environment.
12.3. Compiling Subprograms
A VSI BASIC source file can contain multiple program units. When you compile such a file, VSI BASIC produces a single object file containing the code from all the program units. You can then link this object file to create an executable image.
$
BASIC main,sub1,sub2
To link these programs, you must specify all object files as input to the OpenVMS Linker.
$
BASIC main+sub1+sub2
The plus signs used to separate the file names instruct VSI BASIC to create a single object file called MAIN.OBJ from the three source modules. To link this program, you specify only one input file to the linker.
If the source file contains line numbers, then the line numbers for each subprogram must be numerically greater than the highest line number of all preceding subprograms.
Line numbers must be unique and no greater than 32767.
Each subprogram must end with an END SUB or END FUNCTION statement before the next subprogram begins.
If the source file contains line numbers, then text following an END SUB or END FUNCTION statement must begin on a numbered line.
If the source file does not contain line numbers, then text following an END SUB or END FUNCTION statement must begin on a new physical line.
Note that in a multiple-unit program that contains line numbers, any comments or statements following an END, END SUB, or END FUNCTION statement become part of the preceding subprogram unless they begin on a numbered line. In a multiple-unit program that does not contain line numbers, however, any comments following an END, END SUB, or END FUNCTION statement become part of the following subprogram if one exists.
PROGRAM scan EXTERNAL STRING FUNCTION Strip (STRING) A$ = "USER$DISK:[BASIC.TRYOUTS]" B$ = Strip( A$ ) PRINT B$ END PROGRAM FUNCTION STRING Strip( STRING alpha ) IF (POS( alpha, "[", 1%)) > 0% THEN Strip = EDIT$(alpha, 128% +64%) ELSE Strip = EDIT$(alpha, 128%) END IF END FUNCTION
12.4. Invoking Subprograms
The following sections describe how to invoke subprograms and pass parameters to subprograms.
12.4.1. Invoking SUB Subprograms
The CALL statement transfers control to a subprogram, and optionally passes arguments to it. The parameters in the CALL statement specify variables, constants, expressions, array elements, or entire arrays to be passed to the subprogram. You can also specify a function in the argument list. VSI BASIC passes the value returned by the function to the subprogram. If possible, VSI BASIC converts the actual arguments to the data type specified in the EXTERNAL statement. VSI BASIC signals an error when the conversion is not possible.
PROGRAM get_input OPTION TYPE = EXPLICIT EXTERNAL SUB SUB01(LONG, LONG, LONG) DECLARE LONG A, B, C INPUT "Please type three integers"; A, B, C CALL SUB01 (A, B, C) END PROGRAM SUB SUB01 (LONG X, LONG Y, LONG Z) PRINT "The sum is"; X + Y + Z END SUB
12.4.2. Invoking FUNCTION Subprograms
PROGRAM invoke_funct EXTERNAL LONG FUNCTION FUN01(LONG, LONG, LONG) DECLARE LONG A, B, C INPUT "Please type three integers"; A, B, C PRINT "The sum is"; FUN01(A, B, C) END PROGRAM FUNCTION LONG FUN01 (LONG X, LONG Y, LONG Z) FUN01 = X + Y + Z END FUNCTION
If you do not assign a value to the function name and you do not specify a return value on an EXIT FUNCTION or END FUNCTION statement, the function returns zero or the null string.
Note that when writing FUNCTION subprograms, you must specify a data type for the function in both the main program EXTERNAL statement and the subprogram FUNCTION statement. This data type keyword specifies the data type of the value returned by the function subprogram. You should ensure that the data type specified in an EXTERNAL FUNCTION statement matches the data type specified in the FUNCTION statement.
If you declare a FUNCTION subprogram with an EXTERNAL statement and use the CALL statement to invoke the function, it executes correctly but the function value is not available. Note that BASIC still performs parameter validation when you invoke a function with the CALL statement.
Note that you cannot use the CALL statement to invoke a string or packed decimal function.
12.5. Returning Program Status
A PROGRAM unit lets you return a status from a VSI BASIC image by optionally including an integer expression with the END PROGRAM and EXIT PROGRAM statements. After executing a program, you can examine this status by checking the DCL symbol $STATUS. By default, VSI BASIC returns a status of 1, indicating success. Success is signaled with an odd numbered status value, while an error is signaled with an even numbered value. $STATUS contains the same value as the integer expression for the exit status in the EXIT and END PROGRAM statements. Note that if a program is terminated with an EXIT PROGRAM statement, the expression on the EXIT PROGRAM statement overrides any expression on the END PROGRAM statement.
PROGRAM Venture DECLARE INTEGER exit_status, & REAL capital EXTERNAL LONG CONSTANT SS$_BADPARAM EXTERNAL SUB play_safe(INTEGER), & minor_risk(INTEGER),major_risk(INTEGER) Exit_status = 1% SET NO PROMPT How_much: INPUT "Enter the amount of your free capital $";capital SELECT capital CASE = 0 exit_status = SS$_BADPARAM EXIT PROGRAM exit_status CASE < 5000 CALL play_safe(capital) CASE < 15000 CALL minor_risk(capital) CASE < 50000 CALL major_risk(capital) CASE ELSE PRINT "I can't cope with that amount, try again." END SELECT GOTO How_much . . . END PROGRAM exit_status
$
SHOW SYMBOL $STATUS
$ STATUS = "%X10"
$
error_text = F$MESSAGE(%X10)
$
SHOW SYMBOL error_text
ERROR_TEXT = "SYSTEM-W-BADPARAM, bad parameter value"
The PROGRAM statement is always optional; EXIT PROGRAM and END PROGRAM are legal without a matching PROGRAM statement. Without a PROGRAM statement, these statements still exit the main compilation unit. The EXIT PROGRAM and END PROGRAM statements are not valid within SUB, FUNCTION, or PICTURE subprograms.
Chapter 13. File Input and Output
This chapter explains BASIC file organizations and record operations that are implemented through OpenVMS Record Management Services (RMS). For a more thorough understanding of file organization and file and record operations, see the VSI OpenVMS Record Management Services Reference Manual.
RMS stores data in physical blocks. A block is the smallest number of bytes BASIC transfers in a read or write operation. On disk, a block is 512 bytes. On magnetic tape, it is 18 to 8192 bytes.
RMS stores one or more data records in each block. A data record can also be divided into smaller units, called fields. A data record can be smaller than, equal to, or larger than a disk block.
13.1. Record Formats
Fixed-length records
Variable-length records
Stream records
13.1.1. Fixed-Length Records
Fixed-length records are all the same length. RMS stores fixed-length records as they appear in the record buffer, including any spaces or null characters following the data; this process is called padding. Processing these records involves less overhead than other record formats; however, this format can use disk storage space less efficiently than variable-length or stream records.
13.1.2. Variable-Length Records
Variable-length records can have different lengths, but no record can exceed a maximum size set for the file. When the record is written to a file, RMS adds a record length header that contains the length of the record (excluding the header) in bytes. When your program retrieves a record, this header is not included in the record buffer. While variable-length records usually make more efficient use of storage space than fixed-length records, manipulation of the record length headers generates processor overhead.
13.1.3. Stream Records
BASIC interprets stream records as a continuous sequence, or stream, of bytes. Unlike the fixed- and variable-length formats, stream records do not contain control information such as record counts, segment flags, or other system-supplied boundaries. Stream records are delimited by special characters or character sequences called terminators. Note that stream record formats are valid only in sequential files.
STREAM records can be delimited by any special character (usually a carriage return/line-feed pair).
STREAM_LF records must be delimited by a line-feed character.
STREAM_CR records must be delimited by a carriage return.
While you can access existing files of any one of these stream record formats, BASIC creates new stream files only in the STREAM format; you can create files of the other two stream record formats by modifying the RMS FAB control structure in a USEROPEN routine. For more information about USEROPEN routines, see Section 13.8.11, “USEROPEN Clause”.
13.2. File Organizations
Terminal-format
Sequential
Relative
Indexed
Virtual
If you do not specify a file organization when creating a file, the default is a terminal-format file (a sequential file with variable-length records). The following sections describe each type of file organization.
13.2.1. Terminal-Format Files
A terminal-format file is a sequential file of variable-length records. Terminal-format files are the default; that is, you create a terminal-format file when you do not specify a file organization when you open a file. You can then use the PRINT, INPUT, INPUT LINE, and LINPUT statements to access a terminal-format file. See Chapter 5, Simple Input and Output and Chapter 6, Arrays for more information about terminal-format files.
13.2.2. Sequential Files
A sequential file contains records that are stored in the order they are written. Sequential files can contain records of any valid BASIC record format: fixed-length, variable-length, or stream. You usually read a sequential file from the beginning; therefore, a sequential file is most useful when you access the data sequentially each time you use it. You can also access sequential fixed-length records randomly by specifying a record number if the file resides on disk. In either case, sequential files can reside on both disk and magnetic tape devices, and those stored on disk support shared access.
13.2.3. Relative Files
A relative file contains a series of cells that are numbered consecutively from 1 to n, where n represents the relative record number. Each cell can contain only a single record. For fixed-length records, the length of each cell equals the record length plus 1 byte. For variable-length records, the length of the cell equals the maximum record size plus 3 bytes.
You can access records in a relative file either sequentially or randomly. The relative record number is the key value in random access mode; that is, to access a record in a relative file in random access mode, you must know the relative record number of that record. You can add records to a relative file either at the end of the file or into any empty cell.
Relative files are most useful when randomly accessed and when the record can be identified by its cell number (for example, when inventory numbers correspond to cell numbers). Relative files support shared access. You can delete records from relative files, but not sequential files.
13.2.4. Indexed Files
Strings
WORD integers
LONG integers
Quadword integers
Packed decimal numbers
String keys can also be segmented; the key can be composed of up to eight string variables in a map. Quadword keys must be referenced using a record or group exactly 8 bytes long.
Along with the primary index key value, you can also specify up to 254 alternate keys; RMS creates one index for each key you specify. For each of these keys you can also specify either an ascending or descending collating sequence. Each index is stored as part of the file, and each entry in the index contains a pointer to a record. Therefore, each key you specify corresponds to a sorted list of record pointers.
An indexed file of library books, for example, might be ordered by book title; that is, the title of the book is the primary key for the file. The keys for alternate indexes might include the author's name and the book's Library of Congress number. Neither of these alternate indexes contains the actual records; instead, they contain sorted pointers to the appropriate records.
Indexed files are most useful when randomly accessed or when you want to access the records in more than one way.
13.2.5. Virtual Files
A virtual file is a random access file that stores one or more data records or virtual array elements in each physical 512-byte disk block. You create a virtual file by specifying ORGANIZATION VIRTUAL as part of the OPEN statement. Apart from virtual arrays and compatibility with BASIC and BASIC-PLUS-2, you should use sequential fixed-length instead of virtual files, as they provide the same capabilities. See Section 13.5, “Accessing the Contents of a Record” for more information about accessing the individual records in a disk block.
13.3. Record Access and Record Context
Record access modes determine the order in which your program retrieves or stores records in a file. They determine the record context: the current record and the next record to be processed. When your program successfully executes any record operation, the current record and next record pointers can change. If a record operation is unsuccessful, these pointers do not change.
Sequential access—valid on any file organization
Random-by-record number access—valid on sequential fixed and all relative files
Random-by-key access—valid on indexed files
Random-by-RFA (Record File Address) access—valid on any RMS file located on disk
With sequential access, the next record is the next logical record in the file. In the case of relative files, the next logical record is the next existing record (deleted or never-written records are skipped). In the case of indexed files, the next logical record is the record with the next ascending or descending value in the current key of reference depending on that key's collating sequence. You can therefore access relative or indexed files sequentially by not specifying a relative record number or key value.
You can also access sequential fixed-length and relative files randomly by record number; that is, you can specify the record number of the record to be retrieved. For relative files, this record number corresponds to the cell number of the desired record.
You can access indexed files randomly by key. The key specification includes a primary or alternate key and its value. BASIC retrieves the record corresponding to that value in the particular key chosen.
You can access disk files of any organization by Record File Address (RFA); this means that you specify an RFA variable whose value uniquely identifies a particular record. The RFA requires six bytes of information. For more information about RFAs, see Section 13.6.10, “Accessing Records by Record File Address”.
13.4. I/O and Record Buffers
An I/O buffer is a storage area in your program that RMS uses to store data for I/O operations. You do not have direct access to I/O buffers; they are controlled entirely by RMS. The I/O buffer holds blocks of data transferred from the device, and its size is always greater than or equal to that of the record buffer. For more information about the amount of storage allocated for I/O buffers, see the VSI OpenVMS Record Management Services Reference Manual.
A record buffer is another storage area in your program. You have direct access to and control of the record buffer. When your program reads a record from a file, the information is transferred from the file to the I/O buffer in one large chunk of data, and then the requested record is transferred to the record buffer. When your program writes a record, data is transferred from the record buffer to the I/O buffer, and then to the file either when the I/O buffer is full or when other blocks need to be read in.
You can use MAP statements to create static record buffers and associate program variables with areas (fields) of the buffer. Static record buffers are buffers whose size does not change during program execution and whose program variables are always associated with the same fields in the buffer.
Note
If you do not specify a map, you must use MOVE TO and MOVE FROM statements to transfer data back and forth from the record buffer to program variables; however, MOVE statements do not transfer data to or from a file.
13.5. Accessing the Contents of a Record
MAP statement
MAP DYNAMIC and REMAP statements (dynamic mapping)
MOVE statements
FIELD statements
The FIELD statement is a declining feature and is not recommended for new program development. It is recommended that you use either MAP statements, dynamic mapping, or MOVE statements to access record contents.
13.5.1. MAP Statement
Normally, a record is divided into predetermined fields, the sizes of which are known at compile time. The MAP statement creates the storage area for this record and determines its total size. The following examples show how the MAP statement creates the record storage area:
Example 1
RECORD name_addr STRING last_name = 15, & street_name = 30, & INTEGER house_num END RECORD MAP (student_buffer) name_addr student_info
Example 2
MAP (Emp_rec) STRING Emp_name = 25, & LONG Badge, & STRING Address = 25, & STRING Department = 4
13.5.2. MAP DYNAMIC and REMAP Statements
There are situations where predetermined fields are not applicable or possible. In these situations, you must perform record defielding in your program at run time. Using the MAP DYNAMIC statement, you can specify the variables in the map whose positions can change at run time. The REMAP statement then specifies the new positions of the variables named in the MAP DYNAMIC statement.
MAP (Emp_rec) FILL$ = 2048 MAP DYNAMIC (Emp_rec) & STRING Emp_name, & LONG Badge, & STRING Address, & STRING Department REMAP (Emp_rec) FILL$ = Record_offset, & Emp_name = 25, & Badge, & Address = 25, & Department = 4
DECLARE WORD Record_number MAP (Virt) STRING FILL = 512 MAP DYNAMIC (Virt) STRING First_name, & Last_name, & Company OPEN "VIRT.DAT" FOR INPUT AS FILE #5, & VIRTUAL, MAP Virt Record_number = 1% WHEN ERROR IN WHILE -1% GET #5, RECORD Record_number FOR I% = 0% TO 3% REMAP (Virt) STRING FILL = (I% * 128%), & First_name = 20, & Last_name = 44, & Company = 64 PRINT First_name, Last_name, Company NEXT I% Record_number = Record_number + 1% NEXT USE IF ERR = 11% THEN PRINT "Finished" CONTINUE 32767 ELSE EXIT HANDLER END IF END WHEN END
After the first 512-byte block is brought into memory, the FOR...NEXT loop deblocks the data into 128-byte logical records. At each iteration of the FOR...NEXT loop, the REMAP statement uses the loop variable to mask off 128-byte sections of the block.
For more information about the MAP DYNAMIC and REMAP statements, see Chapter 7, Data Definition and the VSI BASIC Reference Manual.
13.5.3. MOVE Statement
MOVE FROM #9%, A$, Cost, Name$ = 30%, ID_num%
A string field A$ with a default length of 16 characters
A number field Cost of the default data type
A second 30-character string field Name$
An integer field ID_num%
MOVE TO #5%, A$(), C(,), D%(,,), B(3,2)
Successive MOVE statements to or from the buffer start at the beginning of the record buffer. If a MOVE TO operation only partially fills the buffer, the rest of the buffer is unchanged. You use the GET statement to read a record from a file, and then you move the data from the buffer to variables and reference the variables in your program. A MOVE TO operation moves data from the variables into the buffer created by VSI BASIC for OpenVMS. A PUT or UPDATE statement then moves the data from the buffer to the file.
DECLARE STRING Emp_name, Address, Department DECLARE LONG Badge OPEN "MOV.DAT" AS FILE #1%, & RELATIVE VARIABLE, & ACCESS MODIFY, ALLOW NONE, & RECORDSIZE 512% GET #1% MOVE FROM #1%, & Emp_name = 25, & Badge, & Address = 25, & Department = 4 . . . MOVE TO #1%, & Emp_name = 25, & Badge, & Address = 25, & Department = 4 UPDATE #1% CLOSE #1% END
The MOVE TO statement moves the data from the named variables into the buffer. The UPDATE statement writes the record back into file MOV.DAT. The CLOSE statement closes the file.
13.6. File and Record Operations
Open a file for processing with the OPEN statement.
Locate a record in a file with the FIND statement.
Read a record from a file with the GET statement.
Write a record to a file with the PUT statement.
Delete a record from a file with the DELETE statement.
Change the contents of a record field with the UPDATE statement.
Unlock the last record accessed with the UNLOCK statement.
Unlock all previously locked records with the FREE statement.
Write data to a terminal-format file with the PRINT # statement.
Reset the current record pointer to the beginning of a file with the RESTORE # and RESET # statements.
Delete all the records after a certain point; that is, truncate the records, with the SCRATCH statement.
Rename a file with the NAME AS statement.
Close an open file with the CLOSE statement.
Delete an entire file with the KILL statement.
Note that before you can perform any operations on the records in a file, you must first open the file for processing.
13.6.1. Opening Files
The OPEN statement opens a file for processing, specifies the characteristics of the file to RMS, and verifies the result. Opening a file with the specification FOR INPUT specifies that you want to use an existing file. Opening a file with the specification FOR OUTPUT indicates that you want to create a new file. If you do not specify FOR INPUT or FOR OUTPUT, BASIC tries to open an existing file. If no such file exists, a new file is created.
Clauses to the OPEN statement allow you to specify the characteristics of a file. All OPEN statement clauses concerning file or record format are optional when you open an existing file; those attributes that are not specified default to the attributes of the existing file. When you open an existing file, you must specify the file name, channel number, and unless the file is a terminal-format file, an organization clause. If you do not know the organization of the file you want to open, you can specify ORGANIZATION UNDEFINED. If you specify ORGANIZATION UNDEFINED, also specify RECORDTYPE ANY.
If you do not specify a map in the OPEN statement, the size of your program's record buffer is determined by the OPEN statement RECORDSIZE clause, or by the record size associated with the file. If you specify both a MAP clause and a RECORDSIZE clause in the OPEN statement, the specified record size overrides the size specified by the MAP clause.
OPEN "TEST.DAT" FOR OUTPUT AS FILE #1%, & SEQUENTIAL STREAM
MAP (Inv_item) LONG Part_number, & STRING Inv_name = 16, & DOUBLE Unit_price OPEN "INVENTORY.DAT" FOR OUTPUT AS FILE #1% & ,ORGANIZATION RELATIVE FIXED, ACCESS MODIFY & ,ALLOW READ, MAP Inv_item
OPEN "CASE.DAT" AS FILE #1% & ,ORGANIZATION SEQUENTIAL VARIABLE & ,ACCESS READ & ,RECORDSIZE 100%
When you do not specify a MAP statement, your program must use MOVE TO and MOVE FROM statements to move data between the record buffer and a list of variables.
The OPEN statement for indexed files must have a MAP clause. Moreover, if you are creating an indexed file, a PRIMARY KEY clause is required. You can create a segmented index key containing more than one string variable by separating the variables with commas and enclosing them in parentheses. All the string variables must be part of the associated map.
MAP (Segkey) STRING First_name = 15, MI = 1, Last_name = 15 OPEN "NAMES.IND" FOR OUTPUT AS FILE #1%, & ORGANIZATION INDEXED, & PRIMARY KEY (Last_name, First_name, MI), & MAP Segkey
Note that there are restrictions on the maximum record size allowed for various file and record formats. See the VSI OpenVMS Record Management Services Reference Manual for more information.
From DCL command level with the ASSIGN or DEFINE command
From within a program with the SYS$CRELMN system service
BASIC supports any valid logical name as part of a file specification.
$
ASSIGN DUA1:[SENDER]PAYROL.DAT PAYROLL_DATA
$
ASSIGN DUA2: DISK2:
OPEN "PAYROLL_DATA" FOR INPUT AS FILE #1%, & ORGANIZATION SEQUENTIAL OPEN "DISK2:[SORT_DATA] SORT.LIS" FOR OUTPUT AS FILE #2%, & SEQUENTIAL VARIABLE
These OPEN statements do not depend on the availability of DUA1: or DUA2: in order to work. If these devices are not available, you can redefine the logical names so that they specify other disk drives before running the program. In addition, you can redirect the entire file specification for PAYROLL_DATA to point to the test or production version of the data.
13.6.2. Creating Virtual Array Files
BASIC virtual arrays let you define arrays that reside on disk. You use them just as you would an ordinary array. You create a virtual array by dimensioning an array with the DIM # statement, then opening a VIRTUAL file on that channel. You access virtual arrays just as you do normal arrays.
DIM #1%, LONG Int_array(10,10,10) . . . OPEN "VIRT.DAT" FOR OUTPUT AS FILE #1%, VIRTUAL . . . Int_array(5,5,5) = 100%
Note that you cannot redimension virtual arrays with an executable DIM statement. See Chapter 6, Arrays for more information about virtual arrays.
13.6.3. Locating Records
The FIND statement locates a specified record and makes it the current record. Using the FIND statement to locate records can be faster than using a GET statement because the FIND statement does not transfer any data to the record buffer; therefore, it executes faster than a GET statement. However, if you are interested in the contents of a record, you must retrieve it with a GET operation.
Sequential files from beginning to end
Relative files in ascending relative record or cell number order
Indexed files in ascending or descending order, based on the current key of reference and the key's collating sequence
For sequential fixed-length and relative files, you can find a particular record by specifying a RECORD clause. This is called a random access FIND. You can also perform a random access FIND for indexed files by specifying a key of reference, a relational test, and a key value.
MAP (Emp) STRING Emp_name, LONG Emp_number, SSN OPEN "EMP.DAT" AS FILE #1%, INDEXED, & ACCESS READ, & MAP Emp, & PRIMARY KEY Emp_name FIND #1%, KEY #0% NXEQ "SMITH" FIND #1%, KEY #0% NX "JONES"
FIND #5%, KEY #0% EQ "TOM " FIND #5%, KEY #0% EQ "TOM"
The first FIND statement locates a record whose primary key field equals "TOM
"
. The second FIND statement locates the first record whose primary key field begins
with "TOM"
.
Record Access Mode |
File Type |
Current Record |
Next Record |
---|---|---|---|
Sequential FIND |
Sequential |
Record found |
Current record + 1 |
Relative |
Record found |
Next existing record | |
Indexed |
Record found |
Next record in current key order | |
Random access FIND |
All |
Record found |
Unchanged |
Note that a random access FIND operation locates the specified record and makes it the current record, but the next record pointer does not change.
You can specify an ALLOW clause to the FIND statement if you have opened the file with ACCESS MODIFY or ACCESS WRITE and have specified UNLOCK EXPLICIT. The ALLOW clause lets you control the type of lock that RMS puts on the records you access. ALLOW NONE specifies that no other users can access this record (this is the default). ALLOW READ lets other users read the record; however, they cannot perform UPDATE or DELETE operations to this record. ALLOW MODIFY specifies that other users can both read and write to this record. This means that other access streams can perform GET, DELETE, or UPDATE operations to the specified record.
You can also specify a WAIT clause to the FIND statement; this clause allows you to wait for a record to become available in the event that it is currently locked by another process. In addition, you can specify a REGARDLESS clause; this clause allows you to read a locked record. For more information about the WAIT and REGARDLESS clauses, see Section 13.6.9, “Gaining Access to Locked Records”.
13.6.4. Reading Records
The GET statement moves a record from a file to a record buffer and makes the data available for processing. GET statements are valid on sequential, relative, and indexed files. You should not use GET statements on terminal-format files or virtual array files.
For sequential files, a sequential GET retrieves the next record in the file. For relative files, a sequential GET retrieves the next existing record. For indexed files, a sequential GET retrieves the record with the next ascending or descending value in the current key of reference, depending on that key's collating sequence.
Record Access Mode |
File Type |
Current Record |
Next Record |
---|---|---|---|
Sequential GET with FIND |
Sequential |
Record found |
Current record + 1 |
Relative |
Record found |
Next existing record | |
Indexed |
Record found |
Next record in current key | |
Sequential GET without FIND |
Sequential |
Next record |
Next record + 1 |
Relative |
Next existing record |
Next existing record + 1 | |
Indexed |
Next record in current key |
Record following next record in current key | |
Random GET |
All |
Record specified |
Next record in succession |
If you precede a sequential GET operation with a FIND operation, the current record is the one located by FIND. If you do not perform a FIND operation before a sequential GET operation, the current record is the next sequential record.
MAP (Bec) STRING Owner = 30%, LONG Vehicle_number, & STRING Serial_number = 22% OPEN "VEH.IDN" FOR INPUT AS FILE #2%, & ORGANIZATION INDEXED, PRIMARY KEY Serial_number, & MAP Bec, ACCESS READ GET #2%, KEY #0% EQ "AB2721" FOR I% = 1% TO 25% GET #2% PRINT "Vehicle Number = ";Vehicle_number PRINT "Owner is: ";Owner PRINT NEXT I%
MAP (Bec) STRING Owner = 30%, LONG Vehicle_number, & STRING Serial_number = 22% OPEN "VEH.IDN" FOR INPUT AS FILE #2%, & ORGANIZATION SEQUENTIAL FIXED, & MAP Bec, ACCESS READ INPUT "Which record do you want";A% WHILE (A% <> 0%) GET #2%, RECORD A% PRINT "The vehicle number is", Vehicle_number PRINT "The serial number is", Serial_number PRINT "The owner of vehicle";Vehicle_number; "is", Owner INPUT "Next Record";A% NEXT CLOSE #2% END
You can specify an ALLOW clause in a GET statement if you have opened the file with ACCESS MODIFY or ACCESS WRITE and UNLOCK EXPLICIT. The ALLOW clause lets you control the type of lock RMS places on the retrieved record. ALLOW NONE specifies that no other users can access this record (this is the default). ALLOW READ lets other access streams have read access to the record. That is, other users can retrieve the record, but cannot perform DELETE, PUT, or UPDATE operations on it. ALLOW MODIFY lets other access streams perform GET, DELETE, or UPDATE operations on the record.
If you are trying to access a locked record, BASIC signals “Record/bucket locked” (ERR=154). However, if you only need to read this record, you can override the lock with the REGARDLESS clause. The REGARDLESS clause allows you to read a locked record. Use caution when using the REGARDLESS clause because a record accessed in this way might be in the process of being changed by another program.
Alternatively, you can also specify the WAIT clause on a GET statement; the WAIT clause allows you to handle record locked conditions by waiting for the record to become available. Note that if a WAIT clause is specified on a GET operation to a unit-record device such as a terminal, the integer expression indicates how long to wait for the I/O to complete, rather than how long to wait on a record locked condition. For more information, see Section 13.6.9, “Gaining Access to Locked Records”.
13.6.5. Writing Records
For a file opened with ACCESS WRITE or ACCESS MODIFY, the PUT statement moves data from the record buffer to a file using the I/O buffer. PUT statements are valid on RMS sequential, relative, and indexed files. You cannot use PUT statements on terminal-format files or virtual array files.
Record Access Mode |
File Type |
Current Record |
Next Record |
---|---|---|---|
Sequential PUT |
Sequential |
None |
End of file |
Sequential PUT |
Relative |
None |
Next record |
Sequential PUT |
Indexed |
None |
Undefined |
Random PUT |
Relative |
None |
Unchanged |
After a PUT operation, the current record pointer has no value. However, the value of the next record pointer changes depending on the file type and the record access mode used with the PUT operation. In a sequential, stream, or variable file, records can only be added at the end of the file; therefore, the next record after PUT is the end of the file. In a relative, sequential, or fixed file, the next record after a PUT operation is the next logical record.
MAP (Buff) STRING Code = 4%, Exp_date = 9%, Type_desig = 32% OPEN "INV.DAT"FOR INPUT AS FILE #2%, & ORGANIZATION SEQUENTIAL FIXED, ACCESS APPEND, & MAP Buff WHILE -1% INPUT "What is the specification code";Code INPUT "What is the expiration date";Exp_date INPUT "What is the designator";Type_desig PUT #2% NEXT
If the current record pointer is not at the end of the file when you attempt a sequential PUT operation to a sequential file, BASIC signals “Not at end of file” (ERR=149).
10 MAP (Purchase_rec) STRING R_num = 5, & Dept_name = 10, & Pur_dat = 9 20 OPEN "INFO.DAT"FOR OUTPUT AS FILE #2, & ORGANIZATION INDEXED FIXED, ACCESS WRITE, & PRIMARY KEY R_num, MAP Purchase_rec 30 WHILE -1% INPUT "Requisition number";R_num INPUT "Department name";Dept_name INPUT "Date of purchase";Pur_dat PRINT PUT #2% NEXT
Requisition number? 2522A Department name? COSMETICS Date of purchase? 15-JUNE-1985 Requisition number? 2678D Department name? AUTOMOTIVE Date of purchase? 15-JUNE-1985 Requisition number? 4167C Department name? AUTOMOTIVE Date of purchase? 6-JANUARY-1985 Requisition number? 2522A Department name? SPORTING GOODS Date of purchase? 25-FEBRUARY-1985 %BAS-F-DUPKEYDET, Duplicate key detected -BAS-I-ON_CHAFIL, on channel 2 for file USER$$DISK:[MAGNUS]INFO.DAT;8 at user PC 0017E593 -BAS-O-FROLINMOD, from line 30 in module DUPLICATES -RMS-F-DUP, duplicate key detected (DUP not set)
13.6.6. Deleting Records
The DELETE statement removes a record from a file that was opened with ACCESS MODIFY. After you have deleted a record you cannot retrieve it. DELETE works with relative and indexed files only.
FIND #1%, RECORD 67% DELETE #1%
Note
There is no current record after a deletion. The next record pointer is unchanged.
13.6.7. Updating Records
The UPDATE statement writes a new record at the location indicated by the current record pointer. UPDATE is valid on RMS sequential, relative, and indexed files.
UPDATE operates on the current record, provided that you have write access to that record. In order to successfully update a variable-length record, you must know the exact size of the record you want to update. BASIC has access to this information after a successful GET operation. If you have not performed a successful GET operation on the variable-length record, then you must specify a COUNT clause in the UPDATE statement that contains the record size information.
If you are updating a variable length record, and the record that you want to write out is of different size than the record you retrieved, you must use a COUNT clause.
An UPDATE will fail with the exception “No current record” (ERR=131) if you have not previously established a current record with a successful GET or FIND. Therefore, when updating records you should include error trapping in your program to make sure all GET operations execute successfully.
The file containing the record is on disk.
The new record is the same size as the one it is replacing.
You have established a current record through a GET or FIND operation. Note that COUNT defaults to the size of the current record if a GET was performed. If a FIND operation was used to locate the current record, then you must supply a COUNT value.
20 MAP (AAA) STRING L_name = 60%, F_name = 20%, Rm_num = 8% 30 OPEN "STU.DAT"FOR INPUT AS FILE #9%, & ORGANIZATION SEQUENTIAL FIXED, MAP AAA 50 INPUT "Last name";Search_name$ 55 Search_name$ = EDIT$(Search_name$, -1%) 60 IF Search_name$ = "" THEN GOTO 32010 END IF 65 RESTORE #9% 70 WHEN ERROR IN 75 GET #9% WHILE Search_name$ <> L_name USE IF ERR=11 THEN PRINT "No such record" CONTINUE 50 ELSE EXIT HANDLER END IF END WHEN 80 INPUT "Room number";Rm_num 90 UPDATE #9% 100 GOTO 50 32010 CLOSE #9% 32030 PRINT "Update complete" 32767 END
Can be no longer than the maximum record size, if specified
Must include at least the primary key field
MAP (UPD) STRING Enrdat = 8%, LONG Part_num, Sh_num, REAL Cost OPEN "REC.ING"FOR INPUT AS FILE #8%, & INDEXED, MAP UPD, PRIMARY KEY Part_num INPUT "Part number to update";A% Loop1: WHILE -1% GET #8%, KEY #0%, EQ A% INPUT "Revised Cost is";Cost UPDATE #8% INPUT "Next Record";A% IF A% = 0% THEN EXIT Loop1 END IF NEXT CLOSE #8% END
If the new record either omits one of the old record's alternate key fields or changes one of them, the OPEN statement must specify a CHANGES clause for that key field when the file is created. Otherwise, BASIC signals the error “Key not changeable” (ERR=130).
13.6.8. Controlling Record Access
When you open a file, BASIC allows you to specify how you will access the file and what types of access you will allow other running programs while you have the file open.
If you open a file for read access only (ACCESS READ), BASIC by default allows other programs to have unrestricted access to the file. You can restrict access with an ALLOW clause only if the file's security constraints allow you write access to the file.
BASIC by default prevents access by other programs to any file you open with ACCESS WRITE, ACCESS MODIFY, or ACCESS SCRATCH (sequential files only). This default action is equivalent to specifying the OPEN statement ALLOW NONE clause. To allow less restrictive access to the open file, specify ALLOW READ or ALLOW MODIFY.
When a file is open for read access only and you have not restricted access to other programs with ALLOW NONE, BASIC allows other programs to read any record in the file including records that your program is concurrently accessing. However, when you retrieve a record with the GET statement from a file you have opened with the intent to modify, BASIC normally restricts other programs from accessing that record. This restriction is called locking.
Retrieve another record on the same channel. Unless you have opened the file with the UNLOCK EXPLICIT clause (see the following discussion), this action will unlock the previous record.
Explicitly unlock the record with the UNLOCK or FREE statement. The UNLOCK statement releases the current record. The FREE statement releases all records locked on a given channel.
Perform an UPDATE operation on the record. An UPDATE statement causes the current record to be unlocked.
Close the file.
GET #1, ALLOW READ
If you specify UNLOCK EXPLICIT when opening a file, all records that you retrieve remain locked until you explicitly unlock them with a FREE, UNLOCK, or CLOSE statement.
13.6.9. Gaining Access to Locked Records
If you are trying to access a record that is currently locked, one possible solution is to use the REGARDLESS clause on the GET or FIND statement. The REGARDLESS clause is useful when you are interested in having only read access to the specified record. Be aware, however, that using the REGARDLESS clause to read a locked record can lead to unexpected results because the record you read can be in the process of being changed by another program.
Another solution is to include a WAIT clause on the GET or FIND statement. Note that you cannot specify a WAIT clause and a REGARDLESS clause on the same statement line. By specifying the WAIT clause, you can tell RMS to wait for a locked record to become available. You can optionally specify an integer expression from 0 to 255 with the WAIT clause. This integer expression indicates the number of seconds RMS should wait for a locked record to become available. If the record does not become available within the specified number of seconds, RMS signals the error “Keyboard wait exhausted” (ERR=15).
If you do not specify an integer expression with the WAIT clause, RMS waits indefinitely for the record to become available. Once the record becomes available, RMS delivers the record to the program.
Note
If the timeout value specified in the WAIT clause is less than the SYSGEN parameter DEADLOCK_WAIT, then a “Keyboard wait exhausted” (ERR=15) message can indicate that either the record did not become available during the specified time, or there is an actual deadlock situation. However, if the timeout value is greater than the SYSGEN parameter DEADLOCK_WAIT, the system correctly specifies that a deadlock situation has occurred.
MAP (worker) STRING first_name = 10, & last_name = 20, & badge_number = 6, & LONG dept_number MAP (departments) STRING dept_name = 10, & LONG dept_code OPEN "Employee_data.dat" FOR INPUT AS FILE #1%, & INDEXED FIXED, MAP worker, ACCESS MODIFY, & PRIMARY badge_number OPEN "departments.dat" FOR INPUT AS FILE #2, & INDEXED FIXED, MAP departments, ACCESS MODIFY, & PRIMARY dept_code WHEN ERROR IN WHILE -1% GET #1, WAIT WHEN ERROR USE time_expired_handler GET #2%, KEY #0 EQ dept_number, & WAIT 10% END WHEN PRINT badge_number, dept_name NEXT USE SELECT ERR CASE = 11% PRINT "End of file reached" CLOSE 1%, 2% CASE = 193% PRINT "Deadlock detected" UNLOCK #2% RETRY CASE ELSE EXIT HANDLER END SELECT END WHEN HANDLER time_expired_handler IF ERR = 15% OR ERR = 193% THEN PRINT "Department info not available for:" PRINT "Employee ";badge_number PRINT "Going on to next record." CONTINUE ELSE EXIT HANDLER END IF END HANDLER END PROGRAM
The first WHEN ERROR block traps any deadlock conditions. The WHEN ERROR handler unlocks the current record on channel #2 in case another program is trying to access it and then retries the operation. The detached handler for the second WHEN ERROR block traps timeout errors and deadlock errors. If the desired information does not become available in the specified amount of time, or a deadlock condition occurs, the employee's badge number is printed out with an appropriate message, and the GET statement tries to retrieve the next record in the sequence.
13.6.10. Accessing Records by Record File Address
A Record File Address (RFA) uniquely specifies a record in a file. Accessing records by RFA is therefore more efficient and faster than other forms of random record access.?
Because an RFA requires six bytes of storage, BASIC has a special data type, RFA, that denotes
variables that contain RFA information. Variables of data type RFA can be used only with the I/O
statements and functions that use RFA information, and in comparison and assignment statements.
You cannot print these variables or use them in any arithmetic operation. However, you can
compare RFA variables using the equal to (=) and not equal to
(<>)
relational operators.
You cannot create named constants of the RFA data type. However, you can assign values from one RFA variable to another, and you can use RFA variables as parameters.
Explicitly declare the variable or array of data type RFA to hold the address.
Assign the address to the variable or array element. You can do this either with the GETRFA function, or by reading a file of RFAs generated by previous GETRFA functions or by the VMS Sort Utility.
Specify the variable in the RFA clause of a GET or FIND statement.
The GETRFA function returns the RFA of the last record accessed on a channel. Therefore, you must access a record in the file with a GET, FIND, or PUT statement before using the GETRFA function. Otherwise, GETRFA returns a zero, which is an invalid RFA.
DECLARE RFA R_array(1 TO 100) DECLARE LONG I MAP (XYZ) STRING A = 80 OPEN "TEST.DAT" FOR OUTPUT AS FILE #1, & SEQUENTIAL, MAP XYZ FOR I = 1% TO 100% . . . PUT #1 R_array(I) = GETRFA(1%) NEXT I
You can use the RFA clause on GET or FIND statements for any file organization; the only restriction is that the file must reside on a disk that is accessible to the node that is executing the program. An RFA value is only valid for the life of a specific version of a file. If a new version of a file is created, the RFA values might change. If you attempt to access a record with an invalid RFA value, VSI BASIC for OpenVMS signals a run-time error.
DECLARE RFA R_array(1% TO 100%) DECLARE LONG I MAP (XYZ) STRING A = 80 OPEN "TEST.DAT" FOR OUTPUT AS FILE #1, & SEQUENTIAL, MAP XYZ FOR I = 1% TO 100% . . . PUT #1 R_array(I) = GETRFA(1%) NEXT I WHILE -1% PRINT "Which record would you like to see"; INPUT "(type a carriage return to exit)";Rec_num% EXIT PROGRAM IF Rec_num% = 0% GET #1, RFA R_array(Rec_num%) PRINT A NEXT
13.6.11. Transferring Data to Terminal-Format Files
FOR I% = 1% TO 10% INPUT "Name of salesperson":S_name$ INPUT "Sales district";Area$ INPUT "Quantity sold";Quantity% PRINT #4%, S_name$, Area$, Quantity% NEXT I%
If you do not specify an output list in the PRINT # statement, a blank line is written to the terminal-format file. A PRINT statement without a channel number transfers program data to a terminal. See Chapter 5, Simple Input and Output for more information.
13.6.12. Resetting the File Position
RESTORE #3%, KEY #2% RESET #3%
The RESTORE # statement restores the file in terms of the second alternate key. The RESET # statement restores the file in terms of the primary key.
The RESTORE # statement can be used by all RMS file organizations. RESTORE without a channel number resets the data pointer for READ and DATA statements but does not affect any files.
13.6.13. Truncating Files
The SCRATCH statement is valid only on sequential files. Although you cannot delete individual records from a sequential file, you can delete all records starting with the current record through to the end of the file. In order to do this, you must first specify ACCESS SCRATCH when you open the file.
OPEN "MMM.DAT" AS FILE #2%, & SEQUENTIAL FIXED, ACCESS SCRATCH first_bad_record = 33% FIND #2%, RECORD first_bad_record SCRATCH #2% CLOSE #2% END
SCRATCH does not change the physical size of the file; it reduces the amount of information contained in the file. (You can use the DCL command SET FILE/TRUNCATE to truncate the excess file space.) Therefore, you can write records with the PUT statement immediately after a SCRATCH operation.
13.6.14. Renaming Files
NAME "MONEY.DAT" AS "ACCOUNTS.DAT"
Note
The NAME...AS statement can change only the name and directory of a file; it cannot be used to change the device name.
You must always include an output file type because there is no default. If you use the NAME...AS statement on an open file, the new name does not take effect until you close the file.
13.6.15. Closing Files and Ending I/O
At an END, END PROGRAM, or EXIT PROGRAM statement
When it completes the last statement in the program if no END statement exists
While executing a CHAIN statement
Files are not closed after executing a STOP, END SUB, END FUNCTION, or END PICTURE statement.
CLOSE #1% B% = 4% CLOSE #2%, B%, 7% CLOSE I% FOR I% = 1% TO 20%
13.6.16. Deleting Files
KILL "TEST.DAT"
This statement deletes the file named TEST.DAT. Note that this statement deletes only the most current version of the file. Do not omit the file type, because there is no default. You can delete only one file at a time; to delete all versions of a file matching a file specification, use the Run-Time Library routine LIB$DELETE_FILE.
You can delete a file that is currently being accessed by other users; however, the file is not deleted until all users have closed it. You cannot open or access a file once you have deleted it.
13.7. File-Related Functions
The characteristics of the last file opened (FSP$)
The number of bytes moved in the last I/O operation (RECOUNT)
The file status (STATUS, VMSSTATUS, and RMSSTATUS)
These functions are discussed in the following sections.
13.7.1. FSP$ Function
RECORD FSP_data VARIANT CASE BYTE Org BYTE Rat WORD Max_record_size LONG File_size WORD Bucketsize_blocksize WORD Num_keys LONG Max_record_number CASE STRING Ret_string = 16 END VARIANT END RECORD DECLARE FSP_data File_chars OPEN "FIL.DAT" FOR INPUT AS FILE #1%, & ORGANIZATION UNDEFINED, & RECORDTYPE ANY, ACCESS READ File_chars::Ret_string = FSP$(1%)
Rat returns the low byte that is the RMS record attributes (RAT) field.
Org returns the high byte that is the RMS organization (ORG) field.
Max_record_size returns the RMS maximum record size (MRS) field.
File_size returns the RMS allocation quantity (ALQ) field.
Bucketsize_blocksize returns the RMS bucket size (BKS) field for disk files or the RMS block size (BLS) field for magnetic tape files.
Num_keys returns the number of keys.
Max_record_number returns the RMS maximum record number (MRN) field if the file is a relative file.
Note that FSP$ returns zeros in bytes 9 to 12. For more information, see the VSI OpenVMS Record Management Services Reference Manual.
13.7.2. RECOUNT Function
Read operations can transfer varying amounts of data. The system variable RECOUNT contains the number of characters (bytes) read after each read operation.
After a read operation from your terminal, RECOUNT contains the number of characters transferred, including the line terminator. After accessing a record, RECOUNT contains the number of characters in the record.
RECOUNT is reset by every read operation on any channel, including the controlling terminal. Therefore, if you need to use the value of RECOUNT, copy it to another variable before executing another read operation. RECOUNT is undefined if an error occurs during a read operation.
GET #4% bytes_read% = RECOUNT . . . PUT #5%, COUNT bytes_read%
13.7.3. STATUS, VMSSTATUS, and RMSSTATUS Functions
If bit 0 is set, the device type is a record-oriented device.
If bit 1 is set, the device type is a carriage control device.
If bit 2 is set, the device type is a terminal.
If bit 3 is set, the device type is a directory oriented device.
If bit 4 is set, the device type is a single directory device.
If bit 5 is set, the device type is a sequential block-oriented device (magnetic tape or TK50).
Both the VMSSTATUS and RMSSTATUS functions are used to determine which non-BASIC error caused a resulting BASIC error. In particular, VMSSTATUS can be used for any non-BASIC errors, while RMSSTATUS is used specifically for RMS errors. For more information about these functions, see Chapter 15, Handling Run-Time Errors and the VSI BASIC Reference Manual.
13.8. OPEN Statement Options
- BUCKETSIZE
- BUFFER
- CONNECT
- CONTIGUOUS
- DEFAULTNAME
- EXTENDSIZE
- FILESIZE
- NOSPAN
- RECORDTYPE
- TEMPORARY
- USEROPEN
- WINDOWSIZE
13.8.1. BUCKETSIZE Clause
OPEN "STOCK_DATA.DAT" FOR OUTPUT AS FILE #1%, & ORGANIZATION RELATIVE FIXED, BUCKETSIZE 12%
This example specifies a bucket containing approximately 12 records. RMS reads in entire buckets into the I/O buffer at once, and a GET statement transfers one record from the I/O buffer to your program's record buffer.
When you open an existing relative or indexed file and specify a bucket size other than that originally assigned to the file, BASIC signals the error, “File attributes not matched” (ERR=160).
Records cannot span bucket boundaries. Therefore, when you specify a bucket size in your program, you must consider the size of the largest record in the file. Note that a bucket must contain at least one record. Buckets in both relative and indexed files contain information in addition to the records stored in the bucket. You should take this into consideration.
There are two ways to establish the number of blocks in a bucket. The first is to use the default. The second is to specify the approximate number of records you want in each bucket. A bucket size based on that number is then calculated.
The default bucket size assigned to relative and indexed files is as small as possible. A small bucket size, however, is rarely desirable.
Record length
File organization (relative or indexed)
Record format
Assumes that there is a minimum of one record in the bucket
Calculates a size
Assigns the appropriate number of blocks
Note that when you specify a bucket size for files in your program, you must keep in mind the space versus speed tradeoffs. A large bucket size increases file processing speed because a greater amount of data is available in memory at one time; however, it also increases the memory space needed for buffer allocation and the processing time required to search the bucket. Conversely, a small bucket size minimizes buffer requirements, but increases the number of accesses to the storage device, thereby decreasing the speed of operations.
It is recommended that you use the DCL command EDIT/FDL to design files used in production applications where performance is a concern.
13.8.2. BUFFER Clause
The BUFFER clause applies to disk files of any organization. In the case of sequential files, the BUFFER clause sets the number of blocks read in on each disk access. For relative and indexed files, the BUFFER clause determines the number of I/O buffers that are allocated. In general, the OpenVMS operating system supplies adequate defaults for all file types; therefore, the BUFFER clause is rarely necessary.
If (0 < BUFFER < 127), RMS allocates enough space for the specified number of buckets.
If (-128 < BUFFER < 0), BASIC allocates the absolute value of the specified number of buffers.
If (BUFFER=0), BASIC allocates the process default for the particular file organization and device—this value is usually adequate.
13.8.3. CONNECT Clause
MAP (Indmap) WORD Emp_num, & STRING Emp_last_name = 20, & SINGLE Salary, & STRING Wage_code = 2 OPEN "IND.DAT" FOR INPUT AS FILE #1%, & ORGANIZATION INDEXED, & MAP Indmap, & PRIMARY KEY Emp_num, & ALTERNATE KEY Emp_last_name . . . OPEN "IND.DAT" FOR INPUT AS FILE #2% & ORGANIZATION INDEXED, & MAP Indmap, & CONNECT 1
The channel on which you open the file for the first time is called the parent. The CONNECT clause specifies another channel on which you access the same file; connected channels are called children. More than one OPEN statement can connect to the parent channel; however, you cannot connect to a channel that has already been connected to another channel.
Do not use the CONNECT clause when accessing files on remote DECnet nodes.
13.8.4. CONTIGUOUS Clause
A contiguous file with physically adjoining blocks minimizes disk searching and decreases file access time. Once the system knows where a contiguous file starts on the disk, it does not need to use as many retrieval pointers to locate the pieces of that file. Rather, it can access data by calculating the distance from the beginning of the file to the desired data. If there is not enough contiguous disk space, BASIC allocates as much contiguous space as possible. (For truly contiguous records, you must use the USEROPEN clause and set the CTG bit in the FAB FOP field—see the VSI OpenVMS Record Management Services Reference Manual).
Opening a file with both the FILESIZE and CONTIGUOUS clauses pre-extends the file contiguously or in as few disk extents as possible.
13.8.5. DEFAULTNAME Clause
LINPUT "Next data file";Fil$ OPEN Fil$ FOR INPUT AS FILE #5%, & ORGANIZATION SEQUENTIAL, & DEFAULTNAME "USER$DEVICE:.DAT"
The DEFAULTNAME clause supplies default values for the device, directory, and file type portions of the file specification. Typing ABC in response to the Next data file? prompt causes BASIC to try to open USER$DEVICE:ABC.DAT.
BASIC uses the DEFAULTNAME values only if you do not supply those parts of the file specification appearing in the DEFAULTNAME clause. For example, if you type SYS$DEVICE:ABC in response to the prompt, BASIC tries to open SYS$DEVICE:ABC.DAT. In this case, SYS$DEVICE: overrides the device default in the DEFAULTNAME clause. Any part of the file specification still missing is filled in from the current default device and directory of the process.
13.8.6. EXTENDSIZE Clause
OPEN "TSK.ORN" FOR OUTPUT AS FILE #2%, & ORGANIZATION RELATIVE, EXTENDSIZE 128%
The EXTENDSIZE clause causes RMS to add 128 disk blocks whenever the current space allocation is exhausted and the file must be extended.
It must be specified when you create the file
It cannot exceed 65,535 disk blocks
If you specify zero, the extension size equals the RMS default value. The EXTENDSIZE value can be overridden for single OPEN operations.
13.8.7. FILESIZE Clause
OPEN "VALUES.DAT" FOR OUTPUT AS FILE #3%, FILESIZE 50%
The system can create a complete directory structure for the file, instead of allocating and mapping additional disk blocks when needed.
You reserve the needed disk space for your application. This ensures that you do not run out of space when the program is running.
Pre-extension can make some of the file's disk blocks contiguous, especially when used with the CONTIGUOUS keyword.
Note that pre-extension can be a disadvantage if it allocates disk space needed by other users. The FILESIZE clause is ignored when VSI BASIC for OpenVMS opens an existing file.
13.8.8. NOSPAN Clause
By default, sequential files allow records to cross or span block boundaries. If records cross block boundaries, RMS packs records into the file end-to-end throughout the file, leaving space for control information and padding.
The NOSPAN clause overrides this default, forcing records to fit into individual blocks (with space provided for control information and padding). When block boundaries restrict records, fixed-length records must be less than 512 bytes, and variable-length records less than 510 bytes. This can waste extra bytes at the end of each block. However, when records span block boundaries, RMS writes records end-to-end without regard for block boundaries. For example, if you specify NOSPAN, only four 120-byte records fit into a disk block. If you do not specify NOSPAN, BASIC begins writing the fifth record in the block, and continues writing that record in the next block. This minimizes wasted disk space and improves the file's capacity, at the minimal expense of increased processing overhead.
13.8.9. RECORDTYPE Clause
The RECORDTYPE clause lets you specify record formats that are compatible with files created by other language processors. You can choose one of four qualifiers: LIST, FORTRAN, ANY, and NONE. The default for BASIC is LIST, which specifies carriage return format. This is standard for ASCII text files and means that carriage control is performed by RMS when writing the file to a unit-record device.
OPEN "FIL.DAT" FOR INPUT AS FILE #1%, & ORGANIZATION SEQUENTIAL, RECORDTYPE FORTRAN
OPEN "FIL.DAT" FOR INPUT AS FILE #1%, & ORGANIZATION INDEXED, RECORDTYPE ANY
13.8.10. TEMPORARY Clause
When you close the file
When the program aborts or exits
When your process terminates
No entry for this file is made in any directory.
13.8.11. USEROPEN Clause
OPEN "FILE.DAT" FOR INPUT AS FILE #2%, & ORGANIZATION INDEXED, USEROPEN Myopen, MAP ABC
Structure |
Definition |
---|---|
FAB |
File Access Block |
RAB |
Record Access Block |
NAM |
Name Block |
XAB |
FHC Extended Attributes Block |
ESA |
Expanded Name String |
RSA |
Resultant Name String |
A USEROPEN procedure should not alter the allocation of these structures, although it can modify the contents of many of the fields. You should not modify fields set by other OPEN statement keywords. For example, you should use the RECORDSIZE clause, not a USEROPEN routine, to set the record length.
Note
Future releases of the OpenVMS Run-Time Library might alter the use of some RMS fields. Therefore, you might have to alter your USEROPEN procedures accordingly.
BASIC performs normal OPEN statement processing up to the point where it would call the RMS OPEN/CREATE and CONNECT routines. BASIC then passes control to the USEROPEN routine.
BASIC passes the address of the FAB as the first parameter, the address of the RAB as the second parameter, and the address of the user-specified channel number as the third parameter to the routine.
The USEROPEN routine can modify the contents of the RMS control structures, and it must call the RMS OPEN or RMS CREATE routine and the RMS CONNECT routine and return the status in R0.
Note
You cannot use a USEROPEN routine to fill the RBF, UBF, BKS, or CTX fields in the RAB. These fields are filled in after the USEROPEN routine returns; any values placed there by the USEROPEN routine are overwritten. Also, you must not set RMS Locate mode when using a USEROPEN routine on sequential files.
13.8.12. WINDOWSIZE Clause
The WINDOWSIZE clause specifies the number of block retrieval pointers in memory for the file. WINDOWSIZE is not a file attribute, and therefore can be changed any time you open a file.
Retrieval pointers are associated with the file header and point to contiguous blocks on disk. By keeping retrieval pointers in memory, you can reduce the I/O associated with locating a record because the operating system does not have to access the file header for pointers as frequently. The number of retrieval pointers in memory at any one time is determined by the system default or by the value you supply in the WINDOWSIZE clause. The usual default number of retrieval pointers is 7.
A value of zero specifies the default number of retrieval pointers. A value of –1 specifies mapping the entire file, if possible. Values from –128 to –2 are reserved.
Chapter 14. Formatting Output with the PRINT USING Statement
The PRINT USING statement controls the appearance and location of data on a line of output. With it, you can create formatted lists, tables, reports, and forms. This chapter describes how to format data with the PRINT USING statement.
14.1. Overview of the PRINT USING Statement
Rounded to a number of specified decimal places
Vertically aligned on the decimal point
Preceded by a dollar sign
With commas every third digit to the left of the decimal point
Formatting monetary values in this way provides a more readable report. Another use for formatted numeric values might be to print checks on a printer. PRINT USING lets you print numbers with a dollar sign and an asterisk-filled field preceding the first digit.
PRINT USING also formats string data. With it you can left- and right-justify string expressions, or center a string expression over a specified column position. Further, the PRINT USING statement can contain string literals. These are strings that do not control the format of a print item, but instead are printed exactly as they appear in the format string.
It is recommended that you declare all format expressions as string constants. When you do this the VSI BASIC for OpenVMS compiler instructs the Run-Time Library to compile the string at compile time rather than at run time, thus improving the performance of your code.
14.2. Using Format Strings
String variables
String literals
Named string constants
A combination of the previous strings
The PRINT USING statement must contain one or more format strings. Each format string is made up of one format field. Each format field controls the output of one print item and can contain only certain characters, as described throughout the chapter.
The PRINT USING statement must also contain a list of items you want printed. To format print items, you must separate them with commas or semicolons. Separators between print items do not affect output format as they do with the PRINT statement. However, if a comma or semicolon follows the last print item, VSI BASIC for OpenVMS does not return the cursor or print head to the beginning of the next line after it prints the last item in the list.
When VSI BASIC for OpenVMS encounters an invalid character within the current format field, it automatically ends the format field; therefore, you do not need to delimit format fields. The character that terminates the previous field can be either a new format field or a string literal.
PRINT USING "###ABC###", 123, 345
Output
123ABC345
PRINT USING "###ABC###", 123, 345, 564
Output
123ABC345 564ABC
DECLARE STRING CONSTANT format_string = "###.## ###.##" DECLARE SINGLE A,B A = 2.565 B = 100.350 PRINT USING format_string, A, B, A, B
Output
2.57 100.35 2.57 100.35
When the VSI BASIC for OpenVMS compiler encounters the PRINT USING statement, VSI BASIC for OpenVMS prints the value of A (rounded according to PRINT USING rules), three spaces, then the value of B. VSI BASIC for OpenVMS prints the three spaces because they are treated as a string literal in the format string. Notice that when VSI BASIC for OpenVMS reuses a format string, it begins on a new line.
14.3. Printing Numbers
The number of digits to print, thus rounding the number to a given place
The decimal point location, thus vertically aligning numbers at the decimal point
Special symbols, including trailing minus signs (-), asterisk-filled number fields, floating currency symbols, embedded commas, and E notation
Debits and credits
Leading zeros or leading spaces
Blank-if-zero fields
A special character that is to be printed as a literal
Unlike the PRINT statement, PRINT USING does not automatically print a space before and after a number. Unless you reserve enough digit positions to contain the integer portion of the number (and a minus sign, if necessary), VSI BASIC for OpenVMS prints a percent sign (%) to signal this condition and displays the number in PRINT format.
14.3.1. Specifying the Number of Digits
PRINT USING "###",123 !Three places reserved PRINT USING "#####",12345 !Five places reserved PRINT USING "####",-678 !Four places reserved END
Output
123 12345 -678
format_string$ = "#####" PRINT USING format_string$, 1 PRINT USING format_string$, 10 PRINT USING format_string$, -1709 PRINT USING format_string$, 12345 END
Output
1 10 -1709 12345
PRINT USING "###",126.7 PRINT USING "#",5.9 PRINT USING "#",5.4 END
Output
127 6 5
If you have not reserved enough places to print a number's integer portion, VSI BASIC for OpenVMS prints a percent sign as a warning followed by the number in PRINT statement format. After VSI BASIC for OpenVMS prints the number, it completes the rest of the list in PRINT USING format.
PRINT USING "###", 256 PRINT USING "##", 256 END
Output
256 % 256
14.3.2. Specifying Decimal Point Location
DECLARE STRING CONSTANT FM = "##.###" PRINT USING FM, 15.72 PRINT USING FM, 39.3758 PRINT USING FM, 26
Output
15.720 39.376 26.000
PRINT USING "##.##", 25.789 PRINT USING "##.###", 100.2 PRINT USING "#.##",.999 END
Output
25.79 % 100.2 1.00
PRINT USING "##.##", 5.25 PRINT USING "##.##", -5.25 PRINT USING "###.##,-5.25 END
Output
5.25 -5.25 -5.25
14.3.3. Printing Numbers with Special Symbols
Character |
Effect on Format |
---|---|
Number sign (#) |
Reserves a place for one digit. |
Decimal point (period) (.) |
Determines decimal point location and reserves a place for the radix point. |
Comma (,) |
Prints a comma before every third digit to the left of the decimal point and reserves a place for one digit or digit separator. |
Two asterisks (**) |
Print leading asterisks before the first digit and reserve places for two digits. |
Two dollar signs ($$) |
Print a currency symbol before the first digit. They also reserve places for the currency symbol and one digit. By default, the currency symbol is a dollar sign. To change the currency symbol, see Section 14.3.3.3, “Currency Symbols” |
Four carets (^^^^) |
Print a number in E (exponential) format and reserve four places for E notation. |
Minus sign (-) |
Prints a trailing minus sign for negative numbers. Printing a negative number in an asterisk-fill or a currency field requires that the field also have a trailing minus sign or credit/debit character. |
Zero in angle brackets |
Prints leading zeros instead of leading spaces. |
Percent sign in angle brackets |
Prints all spaces in the field if the value of the print item, when rounded to fit the numeric field, is zero. |
CD in angle brackets |
Prints credit and debit characters immediately following the number. BASIC prints CR for negative numbers and zero, and DR for positive numbers. |
Underscore (_) |
Specifies that the next character is a literal, not a formatting character. |
14.3.3.1. Commas
PRINT USING "##,###",10000 PRINT USING "##,###",759 PRINT USING "$$#,###.##",25694.3 PRINT USING "**#,###",7259 PRINT USING "####,#.##",25239 END
Output
10,000 759 $25,694.30 **7,259 25,239.00
14.3.3.2. Asterisk-Fill Fields
DECLARE STRING CONSTANT FM = "**##.##" PRINT USING FM, 1.2 PRINT USING FM, 27.95 PRINT USING FM, 107 PRINT USING FM, 1007.5 END
Output
***1.20 **27.95 *107.00 1007.50
Note that the asterisks reserve two places as well as cause asterisk fill.
DECLARE STRING CONSTANT FM = "**##.##-" PRINT USING FM, 27.95 PRINT USING FM, -107 PRINT USING FM, -1007.5 END
Output
**27.95 *107.00- 1007.50-
If you try to print a negative number in an asterisk-fill field that does not include a trailing minus sign, BASIC signals “PRINT USING format error” (ERR=116).
You cannot specify both asterisk-fill and zero-fill for the same numeric field.
14.3.3.3. Currency Symbols
DECLARE STRING CONSTANT FM = "$$##.##-" PRINT USING FM, 77.44 PRINT USING FM, 304.55 PRINT USING FM, 2211.42 PRINT USING FM, -125.6 PRINT USING FM, 127.82 END
Output
$77.44 $304.55 % 2211.42 $125.60- $127.82
Note that the dollar signs reserve places for the currency symbol and only one digit; the dollar sign is always printed. (Hence the warning indicator (%) when the third PRINT USING statement executes.) Contrast this with the asterisk-fill field, where BASIC prints asterisks only when there are leading spaces.
By default, the currency symbol is a dollar sign. On OpenVMS systems, you can change the currency symbol, radix point, and digit separator by assigning the characters you want to the logical names SYS$CURRENCY, SYS$RADIX_POINT, and SYS$DIGIT_SEP, respectively.
If you try to print a negative number in a dollar sign field that does not include either a trailing minus sign or the CR and DR formatting character, BASIC signals “PRINT USING Format error” (ERR=116).
14.3.3.4. Negative Fields
To allow for a field containing negative values, you must place a trailing minus sign in the format field. A negative format field causes the value to be printed with a trailing minus sign. You can also denote negative fields with CR and DR. See Section 14.3.3.8 for more information.
You must use a trailing minus or the CR/DR formatting character to indicate a negative number in an asterisk-fill or floating dollar sign field.
For fields with trailing minus signs, BASIC prints a minus sign after negative numbers as shown in Example 1, and a space after positive numbers as shown in Example 2.
Example 1
!Standard field PRINT USING "###.##",-10.54 PRINT USING "###.##",10.54 END
Output 1
!Standard field PRINT USING "###.##",-10.54 PRINT USING "###.##",10.54 END
Example 2
!Fields with Trailing Minus Signs PRINT USING "##.##-",-10.54 PRINT USING "##.##-",10.54 END
Output 2
10.54- 10.54
14.3.3.5. E (Exponential) Format
The capital letter E
A plus or minus sign (which indicates a positive or negative exponent)
An exponent (the exponent is 2 digits for single, double, and s_floating, 3 digits for g_floating and t_floating, and 4 digits for h_floating and x_floating)
PRINT USING "###.##^^^^",5 PRINT USING "###.##^^^^",1000 PRINT USING ".##^^^^",5 END
Output
500.00E-02 100.00E+01 .50E+01
PRINT USING "###.##^^^",5 PRINT USING "###.##^^^^^",5 END
Output
5.00^^^ 500.00E-02^
You must reserve a place for a minus sign to the left of the decimal point to display negative numbers in exponential format. If you do not, BASIC prints a percent sign (%) as a warning.
You cannot use exponential format with asterisk-fill, floating-dollar sign, or trailing minus formats.
14.3.3.6. Leading Zeros
(<0>)
. These characters also
reserve one place for a
digit.DECLARE STRING CONSTANT FM = "<0>####.##" PRINT USING FM, 1.23, 12.34, 123.45, 1234.56, 12345.67
Output
00001.23 00012.34 00123.45 01234.56 12345.67
When you specify zero-fill, you cannot specify asterisk-fill or floating-dollar sign format for the same field.
14.3.3.7. Blank-If-Zero Fields
To print a blank field for values which round to zero, you must start the numeric field with a
percent sign enclosed in angle brackets (<%>)
.
DECLARE STRING CONSTANT FM = " <%>####.##" PRINT USING FM, 1000, 0, .001, -5000
Output
1000.00 -5000.00
14.3.3.8. Debits and Credits
<CD>
(Credit/Debit) at the end of the numeric format string. This causes BASIC to
print CR (Credit Record) after negative numbers, and DR (Debit Record) after
positive numbers and
zero.DECLARE STRING CONSTANT FM = "$$####.##<cd>" PRINT USING FM, -552.35, 200, -5
Output
$552.35CR $200.00DR $5.00CR
You cannot use a trailing minus sign and Credit/Debit formatting in the same numeric field. Using the Credit/Debit formatting character causes the value to be printed with a leading space.
14.4. Printing Strings
The number of characters
Left-justified format
Right-justified format
Centered format
Extended field format
Character |
Effect on Format |
---|---|
Single quotation mark ( ’) |
Starts the string field and reserves a place for one character. |
L (upper- or lowercase) |
Left-justifies the string and reserves a place for one character. |
R (upper- or lowercase) |
Right-justifies the string and reserves a place for one character. |
C (upper- or lowercase) |
Centers the string in the field and reserves a place for one character. |
E (upper- or lowercase) |
Left-justifies the string; expands the field, as necessary, to print the entire string; and reserves a place for one character. |
Two backslashes ( \ \) |
Reserves n+2 character positions, where n is the number of spaces between the two backslashes. PRINT USING left-justifies the string in this field. This formatting character is included for compatibility with BASIC-PLUS. It is recommended that you not use this type of field for new program development. |
Exclamation point (!) |
Creates a 1-character field. The exclamation point both starts and ends the field. This formatting character is included for compatibility with BASIC-PLUS. It is recommended that you not use this type of field for new program development. Instead, use a single quotation mark to create a 1-character field. |
A contiguous series of upper- or lowercase Ls for left-justified output
A contiguous series of upper- or lowercase Rs for right-justified output
A contiguous series of upper- or lowercase Cs for centered output
A contiguous series of upper- or lowercase Es for extended field output
BASIC ignores the overflow of strings larger than the string format field except for extended fields. For extended fields, BASIC extends the field to print the entire string. If a string to be printed is shorter than the format field, BASIC pads the string field with spaces. For more information about extended fields, see Section 14.4.4, “Extended Fields”.
PRINT USING "'","ABCDE" END
Output
A
See Section 14.4.4, “Extended Fields” for an example of different types of fields used together.
14.4.1. Left-Justified Format
BASIC prints strings in a left-justified field starting with the leftmost character. BASIC pads shorter strings with spaces and truncates longer strings on the right to fit the field.
PRINT USING "'LLLLLL","ABCDE" PRINT USING "'LLLL","ABC" PRINT USING "'LLLLL","12345678" END
Output
ABCDE ABC 123456
14.4.2. Right-Justified Format
BASIC prints strings in a right-justified field starting with the rightmost character. BASIC pads the left side of shorter strings with spaces. If a string is longer than the field, BASIC left-justifies and truncates the right side of the string.
DECLARE STRING CONSTANT right_justify = "'RRRRR" PRINT USING right_justify,"ABCD" PRINT USING right_justify,"A" PRINT USING right_justify,"STUVWXYZ" END
Output
ABCD A STUVWX
14.4.3. Centered Fields
BASIC prints strings in a centered field by aligning the center of the string with the center of the field. If BASIC cannot exactly center the string—as is the case for a 2-character string in a 5-character field, for example—BASIC prints the string one character off center to the left.
DECLARE STRING CONSTANT center = "'CCCC" PRINT USING center, "A" PRINT USING center, "AB" PRINT USING center, "ABC" PRINT USING center, "ABCD" PRINT USING center, "ABCDE"
Output
A AB ABC ABCD ABCDE
If there are more characters than places in the field, BASIC left-justifies and truncates the string on the right.
14.4.4. Extended Fields
If the string is smaller than the format field, BASIC left-justifies the string as in a left-justified field.
If the string is longer than the format field, BASIC extends the field and prints the entire string.
PRINT USING "'E", "THE QUICK BROWN" PRINT USING "'EEEEEEE', "FOX" END
Output
THE QUICK BROWN FOX
PRINT USING "'LLLLLLLLL","THIS TEXT" PRINT USING "'LLLLLLLLLLLLLL","SHOULD PRINT" PRINT USING "'LLLLLLLLLLLLLL",'AT LEFT MARGIN' PRINT USING "'RRRR","1,2,3,4" PRINT USING "'RRRR",'1,2,3' PRINT USING "'RRRR',"1,2" PRINT USING "'RRRR","1" PRINT USING "'CCCCCCCCC","A" PRINT USING "'CCCCCCCCC","ABC" PRINT USING "'CCCCCCCCC","ABCDE" PRINT USING "'CCCCCCCCC","ABCDEFG" PRINT USING "'CCCCCCCCC","ABCDEFGHI" PRINT USING "'LLLLLLLLLLLLLLLLL',"YOU ONLY SEE PART OF THIS" PRINT USING "'E","YOU CAN SEE ALL OF THE LINE WHEN IT IS EXTENDED" END
Output
THIS TEXT SHOULD PRINT AT LEFT MARGIN 1,2,3 1,2,3 1,2 1 A ABC ABCDE ABCDEFG ABCDEFGHI YOU ONLY SEE PART YOU CAN SEE ALL OF THE LINE WHEN IT IS EXTENDED
14.5. PRINT USING Statement Error Conditions
The format string is not a valid string expression
There are no valid fields in the format string
You specify a string for a numeric field
You specify a number for a string field
You separate the items to be printed with characters other than commas or semicolons
A format field contains an invalid combination of characters
You print a negative number in a floating-dollar sign or asterisk-fill field without a trailing minus sign
BASIC issues a warning if a number does not fit in the field. If a number is larger than the field allows, BASIC prints a percent sign (%) followed by the number in the standard PRINT format and continues execution.
If a string is larger than any field other than an extended field, BASIC truncates the string and does not print the excess characters.
If a field contains an invalid combination of characters, BASIC does not recognize the first invalid character or any character to its right as part of the field. These characters might form another valid field or be considered text. If the invalid characters form a new valid field, a fatal error condition might arise if the item to be printed does not match the field.
The following examples demonstrate invalid character combinations in numeric fields:
Example 1
PRINT USING "$$**##.##",5.41,16.30
The dollar signs form a complete field and the rest forms a second valid field. The first number (5.41) is formatted by the first valid field ($$). It prints as “$5”. The second number (16.30) is formatted by the second field (**##.##) and prints as “**16.30”.
Output 1
$5**16.30
Example 2
PRINT USING "##.#^^^",5.43E09
Because the field has only three carets instead of four, BASIC prints a percent sign and the number, followed by three carets.
Output 2
% .543E+10^^^
Example 3
PRINT USING "'LLEEE","VWXYZ"
You cannot combine two letters in one field. BASIC interprets EEE as a string literal.
Output 3
VWXEEE
Chapter 15. Handling Run-Time Errors
The process of detecting and correcting errors that occur when your program is running is called error handling. This chapter describes default error handling and how to handle VSI BASIC for OpenVMS run-time errors with your own error handlers.
Throughout this chapter, the term “error” is used to imply any OpenVMS exception, not only an exception of ERROR severity.
15.1. Default Error Handling
VSI BASIC for OpenVMS provides default run-time error handling for all programs. If you do not provide your own error handlers, the default error handling procedures remain in effect throughout program execution time.
When an error occurs in your program, VSI BASIC for OpenVMS diagnoses the error and displays a message telling you the nature and severity of the error. There are four severity levels of VSI BASIC for OpenVMS errors: SEVERE, ERROR, WARNING, and INFORMATIONAL. The severity of an error determines whether or not the program aborts if the error occurs when default error handling is in effect. When default error handling is in effect, ERROR and SEVERE errors always terminate program execution, but program execution continues when WARNING and INFORMATIONAL errors occur.
To override the default error handling procedures, you can provide your own error handlers, as described in the following sections. (Note that you should not call LIB$ESTABLISH from a VSI BASIC for OpenVMS program as this RTL routine overrides the default error handling procedures and might adversely affect program behavior).
Only one error can be handled at a time. If an error has occurred but has not yet been handled completely, that error is said to be pending. When an error is pending and a second error occurs, program execution always terminates immediately. Therefore, one of the most important functions of an error handler is to clear the error so that subsequent errors can also be handled.
If you do not supply your own error handler, program control passes to the VSI BASIC for OpenVMS error handler when an error occurs. For example, when VSI BASIC for OpenVMS default error handling is in effect, a program will abort when division by zero is attempted because division by zero is an error of SEVERE severity. With an error handler, you can include an alternative set of instructions for the program to follow; if the zero was input at a terminal, a user-written error handler could display a “Try again” message and execute the program lines again requesting input.
15.2. User-Supplied Error Handlers
It is good programming practice to anticipate certain errors and provide your own error handlers for them. User-written error handlers allow you to handle errors for a specified block of program statements as well as complete program units. Any program module can contain one or more error handlers. These error handlers test the error condition and include statements to be executed if an error occurs.
To provide your own error handlers, you use WHEN ERROR constructs. A WHEN ERROR construct consists of two blocks of code: a protected region and a handler. A protected region is a block of code that is monitored by the compiler for the occurrence of an error. A handler is the block of code that receives program control when an error occurs during the execution of the statements in the protected region.
There are two forms of WHEN ERROR constructs; in both cases the protected region begins immediately after a WHEN ERROR statement. The following partial programs illustrate each form. In Example 1, the handler is attached to the protected region, while in Example 2, the handler catch_handler is detached and must be provided elsewhere in the program unit.
WHEN ERROR IN protected_statement_1 protected_statement_2 . . . USE handler_statement_1 handler_statement_2 . . . END WHEN
WHEN ERROR USE catch_handler protected_statement_1 protected_statement_2 . . . END WHEN HANDLER catch_handler handler_statement_1 handler_statement_2 . . . END HANDLER
The following sections further explain the concepts of protected regions and handlers.
15.2.1. Protected Regions
A protected region is a block of code that is monitored by the compiler for the occurrence of an error. The bounds of this region are determined by the actual ordering of the source code. Statements that are lexically between a WHEN ERROR statement and a USE or END WHEN statement are in the protected region.
If an error occurs inside the protected region, control passes to the error handler associated with the WHEN ERROR statement. When an error occurs beyond the limits of a protected region, default error handling is in effect unless other error handlers are provided. For more details about handler priorities, see Section 15.2.3 and Section 15.3.
The WHEN ERROR statement signals the start of a block of protected statements. The WHEN ERROR statement also specifies the handler to be used for any errors that occur inside the protected region. The keyword USE either explicitly names the associated handler for the protected region, or marks the start of the actual handler statements. The statements in the actual error handler receive control only if an error occurs in the protected region.
DECLARE INTEGER value_1, value_2 WHEN ERROR IN INPUT "PLEASE INPUT 2 INTEGERS"; value_1, value_2 !protected statement USE PRINT "INVALID INPUT - PLEASE TRY AGAIN" !handler statement RETRY !handler statement END WHEN PRINT "THEIR SUM IS"; value_1 + value_2
Protected regions can be nested; a protected region can be within the bounds of another protected region. However, WHEN ERROR statements cannot appear inside an error handler, and protected regions cannot cross over into other block structures. If you are using a WHEN ERROR block with a detached handler, that handler cannot exist within a protected region.
15.2.2. Handlers
Determines which error occurred
Takes appropriate action based on the nature of the error
Clears the error condition with a RETRY, CONTINUE, END WHEN, or END HANDLER statement
Continues program execution when possible
Possibly identifies which program unit or statement caused the error
Resignals errors with EXIT HANDLER (when an error cannot be handled for some reason)
Handlers can be attached to, or detached from, the statements in the WHEN ERROR protected region.
PROGRAM accident_prone DECLARE REAL age, accidents, rating WHEN ERROR IN Get_age: INPUT "Enter your age";age INPUT "How many serious accidents have you had";accidents rating = accidents/age PRINT "That's ";rating;" serious accidents per year!" USE SELECT ERR !Trap division by zero CASE = 61 PRINT "Please enter an age greater than 0" CONTINUE Get_age !Trap illegal number CASE = 52 PRINT "Please enter a positive number" RETRY CASE ELSE !Revert to default error handling EXIT HANDLER END SELECT END WHEN END PROGRAM
WHEN ERROR USE catcher KILL "INPUT.DAT" END WHEN . . . HANDLER catcher !Catch if file does not exist IF ERR = 5 THEN CONTINUE END IF END HANDLER
The statements within a handler are never executed if an error does not occur or if no protected region exists for the statement that caused the exception.
When your program generates an error, control transfers to the specified handler. If the code in an error handler generates a second error, control returns to the default VSI BASIC for OpenVMS error handler and program execution ends, usually with the first error only partly processed. To avoid the possibility of your error handler causing a second error, you should keep handlers as simple as possible and keep operations that might cause errors outside the handler.
PROGRAM Check_records WHEN ERROR USE Global_handler . . . END WHEN HANDLER Global_handler SELECT ERR !Trap buffer overflow CASE = 161 PRINT "Record too long" CONTINUE !Trap end of file on device CASE = 11 PRINT "End of file" CONTINUE CASE ELSE EXIT HANDLER END SELECT END HANDLER CLOSE #1% END PROGRAM
Note that ON ERROR statements are not allowed within protected regions or handlers. For compatibility issues related to ON ERROR statements, see Section 15.3, “Using the ON ERROR Statements”.
15.2.3. Exiting from Handlers
- RETRY
- CONTINUE
- END HANDLER
- END WHEN
These statements differ from each other in that they revert control of program execution to different points in the program. Examples of these statements are included in the following sections.
An additional statement, EXIT HANDLER, is provided to allow you to exit from a handler with the error still pending.
The END HANDLER statement identifies the end of the block of statements in the handler. The END WHEN statement marks the end of the protected region when a detached handler is used; it marks the end of the handler when an attached handler is used. If the handler does not process an error with an EXIT HANDLER, RETRY, or CONTINUE statement, the error is cleared by the END HANDLER or END WHEN statement; however, processing continues with the statement immediately after the protected region (and the attached handler, if one exists) where the error occurred. These statements do not return control to the protected region. This is known as “falling out of the bottom of a handler.” Be careful not to fall out of the bottom of a handler unintentionally.
EXIT PROGRAM
EXIT FUNCTION
EXIT SUB
EXIT DEF
GOSUB (with a target outside the handler)
GOTO (with a target outside the handler)
Also, you cannot exit from a handler with a RESUME statement. The RESUME statement is valid only in blocks of code referred to by ON ERROR statements. Section 15.3, “Using the ON ERROR Statements” describes the ON ERROR statements.
15.2.3.1. RETRY Statement
DECLARE REAL radius WHEN ERROR USE fix_it INPUT "Please supply the radius of the circle"; radius END WHEN HANDLER fix_it !trap overflow error IF ERR = 48 PRINT "Please supply a smaller radius" RETRY END HANDLER PRINT "The circumference of the circle is "; 2*PI*radius
In FOR...NEXT loops, if the error occurs while VSI BASIC for OpenVMS is evaluating the limit or increment values, RETRY reexecutes the FOR statement; if the error occurs while VSI BASIC for OpenVMS is evaluating the index variable, RETRY reexecutes the NEXT statement. In UNTIL...NEXT and WHILE...NEXT loops, if the error occurs while VSI BASIC for OpenVMS is evaluating the relational expression, RETRY reexecutes the NEXT statement.
15.2.3.2. CONTINUE Statement
You can use the CONTINUE statement to clear the error and cause execution to continue at the statement immediately following the propagated error.
DIM LONG her_attributes(10),his_attributes(10) DECLARE INTEGER counter WHEN ERROR USE fix_it DATA 12,2,35,21,25.5,32,32,30,15,4 FOR counter = 0 TO 12 READ her_attributes(counter) NEXT counter MAT his_attributes = her_attributes END WHEN . . . HANDLER fix_it !Trap out of data IF ERR = 57 THEN RESTORE CONTINUE ELSE EXIT HANDLER END IF END HANDLER
When a DEF function is invoked from a protected region and an error occurs that has not been handled, a CONTINUE statement with no target causes execution to resume at the statement following the one that invoked the function.
Note
When you use the RETRY or the CONTINUE statement without a target, the compiler builds read only tables in the generated object file with information about statements in the associated protected regions. Therefore, when space is extremely critical, do not protect large regions with handlers containing RETRY or CONTINUE without a specified target.
15.2.3.3. EXIT HANDLER Statement
Unlike RETRY and CONTINUE, the EXIT HANDLER statement does not clear the error; rather, it allows you to exit from the handler with the error pending. This allows you to pass an error to the handler associated with the next outer protected region, or back to VSI BASIC for OpenVMS default error handling, or to the calling procedure.
When an error occurs within a nested protected region, control passes to the handler associated with the innermost protected region in which the error occurred. If the innermost handler does not handle the error, the error is passed to the next outer handler with the EXIT HANDLER statement. All handlers for any outer WHEN ERROR blocks are processed before reverting to default error handling or resignalling the calling procedure.
PROGRAM nesting OPTION TYPE = EXPLICIT DECLARE LONG divisor DECLARE REAL dividend, quotient WHEN ERROR USE outer_handler INPUT "Enter divisor";Divisor INPUT "Enter dividend";Dividend WHEN ERROR USE inner_handler Quotient = Dividend/Divisor PRINT "The quotient is ";Quotient END WHEN END WHEN HANDLER outer_handler !Trap data format error IF ERR = 50 THEN PRINT "Illegal input...try again" RETRY ELSE PRINT "In outer_handler" PRINT "Reverting to default handling now" EXIT HANDLER END IF END HANDLER HANDLER inner_handler !Trap overflow/decimal error IF ERR = 181 THEN CONTINUE ELSE PRINT "Inside inner_handler" PRINT "Reverting to outer handler now" EXIT HANDLER END IF END HANDLER END PROGRAM
For more information about exiting program units while an error is pending, see Section 15.2.6, “Ctrl/C Trapping”.
15.2.4. Selecting the Severity of Errors to Handle
The OPTION HANDLE statement lets you specify the severity level of errors that are to be handled by an error handler in addition to the BASIC errors that can normally be handled or trapped. You can specify any one of the following error severity levels: BASIC, SEVERE, ERROR, WARNING, or INFORMATIONAL.
OPTION HANDLE = BASIC is the default, which is in effect if you do not specify an alternative in the OPTION HANDLE statement. Only VSI BASIC for OpenVMS errors that can be trapped transfer control to the current error handler when this option is in effect. Refer to Appendix B, Run-Time Messages to determine which BASIC errors cannot be trapped.
All BASIC errors that can be trapped of this or lesser severity
All non-BASIC errors of this or lesser severity
BASIC errors of this or lesser severity that normally cannot be trapped
For example, if you specify OPTION HANDLE = ERROR, you can handle all BASIC and non-BASIC errors of ERROR severity (both those that can and those that cannot be trapped), and all WARNING and INFORMATIONAL errors, but no SEVERE errors.
15.2.5. Identifying Errors
- ERR
- ERL
- ERN$
- ERT$
- VMSSTATUS
- RMSSTATUS
Note that if an error occurs in your program that is not a VSI BASIC for OpenVMS error or does not map onto a VSI BASIC for OpenVMS error, it is signaled as NOTBASIC ( “Not a BASIC error” (ERR=194). In this case, you can use the built-in function VMSSTATUS to determine what caused the error.
15.2.5.1. Determining the Error Number (ERR)
OPTION HANDLE = ERROR WHEN ERROR USE find_error . . . END WHEN HANDLER find_error SELECT ERR !Record already exists CASE = 153 PRINT "Choose new record" CONTINUE CASE ELSE EXIT HANDLER END SELECT END HANDLER
The results of ERR remain undefined until an error occurs. Although ERR remains defined as the number of the last error after control leaves the error handler, it is poor programming practice to refer to this variable outside the scope of an error handler.
15.2.5.2. Determining the Error Line Number (ERL)
After your program generates an error, the ERL function returns the BASIC line number of the signaled error. This function is valid only in line-numbered programs. The ERL function, like ERR, lets you set up branching to one of several paths in the code.
10 DECLARE INTEGER CONSTANT TRUE = -1 20 WHEN ERROR USE err_handler . . . 900 END WHEN 1000 HANDLER err_handler SELECT TRUE CASE (ERR = 11) AND (ERL = 790) !Is error end of file at line 790? PRINT "Completed" CONTINUE CASE (ERR = 149) AND (ERL = 80) !Is error not at end of file on line 80? PRINT "CHECK ACCESS MODE" CONTINUE CASE ELSE !Let BASIC handle any other errors EXIT HANDLER 1500 END SELECT 2000 END HANDLER 32000 CLOSE #5 32767 END
The results of ERL are undefined until an error occurs, or if the error occurs in a subprogram not written in VSI BASIC for OpenVMS. Although ERL remains defined as the line number of the last error even after control leaves the error handler, it is poor programming practice to refer to this variable outside the scope of an error handler.
If you reference ERL in a compilation unit with line numbers, code and data are included in your program to allow VSI BASIC for OpenVMS to determine ERL when an exception occurs. If you do not need to reference ERL, you can save program size and reduce execution time by compiling your program with the /NOLINE qualifier. Alpha BASIC uses the /NOLINE qualifier by default to compile programs. Even if you do not use any line numbers, you can reduce execution time by compiling with the /NOLINE qualifier.
If an error occurs in a subprogram containing line numbers, VSI BASIC for OpenVMS sets the ERL variable to the subprogram line number where the error was detected. If the subprogram also executes an EXIT HANDLER statement, control passes back to the outer procedure's handler. The error is assumed to occur on the statement where the call or invocation occurs.
15.2.5.3. Determining Where the Error Occurred (ERN$)
You use the ERN$ function to return the name of the program unit in which the error was detected. ERN$ returns the name of a main program, SUB, FUNCTION, or PICTURE subprogram, or DEF function. If the PROGRAM statement is used with a user-supplied identifier, the ERN$ value is the specified identifier for the main program. The results of ERN$ are undefined until the program generates an error.
HANDLER locat_ern IF ERN$ = "SUBARC" THEN PRINT "ERROR IS ";ERR PRINT "RETURNING TO MAIN PROGRAM FOR ERROR HANDLING" EXIT HANDLER ELSE PRINT "PROGRAM MODULE GENERATING ERROR IS ";ERN$ END IF END HANDLER
Note that ERN$ is invalid when an error occurs in a subprogram compiled with the /NOSETUP qualifier.
15.2.5.4. Determining the Error Message Text (ERT$)
HANDLER catch_it IF ERN$ = "TSLFE" THEN PRINT ERT$(ERR) CONTINUE ELSE EXIT HANDLER END IF END HANDLER
15.2.5.5. Determining OpenVMS Error Information
VSI BASIC for OpenVMS provides a built-in function, VMSSTATUS, that returns the originally signaled error before it is translated to a BASIC error. For example, for the BASIC error “End of file on device” (ERR=11), the VMSSTATUS function returns “RMS$_EOF” (RMS end of file). This function is useful when the error is NOTBASIC (ERR=194).
When there is no error pending, VMSSTATUS is undefined. The value returned by this function is the actual signaled error value. If non-BASIC errors are being handled, the VMSSTATUS function might be the only way to find out which error caused the exception.
PROGRAM Tester OPTION HANDLE = ERROR EXTERNAL LONG CONSTANT BAS$K_RECNOTFOU, BAS$K_RECBUCLOC DECLARE LONG Final_status MAP (Rec_buffer) & STRING Rec_key = 5, & STRING Rest_of_record = 20 Final_status = 1 WHEN ERROR USE Global_handler OPEN "My_database" FOR INPUT AS FILE #1 & ,INDEXED FIXED & ,ACCESS READ & ,MAP Rec_buffer & ,PRIMARY Rec_key Get_key: INPUT "Record to retrieve"; Rec_key WHEN ERROR IN GET #1%, KEY #0 EQ Rec_key PRINT Rest_of_record USE SELECT ERR CASE = BAS$K_RECNOTFOU PRINT "Record not found" CONTINUE Get_key CASE = BAS$K_RECBUCLOC SLEEP 2% RETRY CASE ELSE EXIT HANDLER END SELECT END WHEN END WHEN HANDLER Global_handler Final_status = VMSSTATUS END HANDLER END PROGRAM Final_status
15.2.5.6. Determining RMS Error Information
The RMSSTATUS function lets you determine which RMS error caused a resulting VSI BASIC for OpenVMS error. You must specify an open channel as the first parameter to RMSSTATUS. If this channel is not open, the error “I/O channel not open” (ERR=9) is signaled. The second parameter to the function lets you specify either STATUS or VALUE; this parameter is optional. If you do not specify the second parameter, RMSSTATUS returns the STATUS value by default. STATUS represents the RMS STS field and VALUE corresponds to the RMS STV field.
WHEN ERROR IN OPEN "file.txt" FOR OUTPUT AS FILE 1% PRINT #1%, TIME$(0%) USE !Error 12 is fatal system I/O failure IF ERR = 12 THEN PRINT "An unexpected RMS error has occurred:" PRINT "Status = "; RMSSTATUS(1%) PRINT "Value = "; RMSSTATUS(1%, VALUE) EXIT HANDLER END IF END WHEN CLOSE #1% GOTO done done: END
If you want to find an RMS status without knowing which particular channel to check, you can use VMSSTATUS to get the STATUS value (STS) if an error has occurred.
15.2.6. Ctrl/C Trapping
Y% = CTRLC
WHEN ERROR IN Y% = CTRLC OPEN 'FIL_DAT' FOR INPUT AS FILE #1% INPUT "HOW MANY RECORDS"; Rec_read% FOR I% = 1% TO Rec_read% GET #1% PRINT Name$, Address$, Emp_code% PRINT NEXT I% USE !Trap ^C IF (ERR = 28%) THEN PRINT "CURRENT RECORD IS "; I% ELSE EXIT HANDLER END IF CONTINUE Clean_up END WHEN . . . Clean_up: CLOSE #1% PRINT "END OF PROCESSING" END
Output
SMITH, DEXTER 231 COLUMBUS ST 09341 TRAVIS, JOHN PO BOX 80 64119 ^C THE CURRENT RECORD IS 3 END PROCESSING
Note that the error condition is still pending until the error handler executes the CONTINUE statement. Therefore, if you press Ctrl/C a second time while the error handler is executing, control returns to the VSI BASIC for OpenVMS error handler, which terminates the program.
To disable Ctrl/C trapping, use the RCTRLC function. The RCTRLC function disables only Ctrl/C trapping, not the Ctrl/C interrupts themselves.
15.2.7. Handling Errors in Multiple-Unit Programs
You can use WHEN ERROR constructs anywhere in your main program or program modules. Procedure and function invocations, such as invocations of DEF and DEF* functions and SUB, FUNCTION, and PICTURE subroutines, as well as non-BASIC programs, are valid within protected regions. GOTO and GOSUB statements are valid within handlers provided that the target is within the handler, an outer handler, or an unprotected region. Note, however, that a detached handler cannot appear within DEF or DEF* functions without the associated protected region.
SUB LIST(A$) WHEN ERROR USE sub_handler OPEN A$ FOR INPUT AS FILE #12% Get_data: LINPUT #12%, B$ PRINT B$ GOTO Get_data END WHEN HANDLER sub_handler !Trap end of file IF ERR <> 11% THEN EXIT HANDLER END IF END HANDLER CLose_up: CLOSE #12% END SUB
You can call a subprogram while an error is pending; however, if you do, the subprogram cannot resignal an error back to the calling program. If the subprogram tries to resignal an error, VSI BASIC for OpenVMS signals “Improper error handling” and program execution terminates.
DEF and DEF* function definitions cannot appear within a protected region. However, protected regions can be contained within the function definitions.
To trap errors while a DEF function is active, include protected regions inside the DEF function. If you do this, the associated handler remains in effect until your program leaves the protected region, or the DEF function.
WHEN ERROR IN . . . Invoke_def: A% = FNIN_PUT%("PROMPT") USE PRINT "ERROR"; ERT$(ERR%); IF ERN$ = "FNIN_PUT" THEN PRINT "IN FUNCTION" CONTINUE ELSE PRINT "IN MAIN" CONTINUE Invoke_def END IF END WHEN Main_code: DEF FNIN_PUT%(P$) WHEN ERROR IN PRINT P$ INPUT LINE_IN$ FNIN_PUT% = INTEGER(LINE_IN$) USE IF ERR = 50 THEN RETRY ELSE EXIT HANDLER END IF END WHEN END DEF
15.2.8. Forcing Errors
CAUSE ERROR 11%
WHEN ERROR IN . . . CAUSE ERROR 11% . . . USE SELECT ERR CASE = 11% PRINT "Trapped an end of file on device" CONTINUE CASE ELSE EXIT HANDLER END WHEN
15.3. Using the ON ERROR Statements
VSI BASIC for OpenVMS supports ON ERROR statements as an alternative to WHEN blocks primarily for compatibility with existing programs. WHEN ERROR blocks are similar to declarative statements in that they do not depend on run-time flow of control. The ON ERROR statements, however, affect error handling only if the statements execute at run time. For example, if a GOTO statement precedes an ON ERROR statement, the ON ERROR statement will not have any effect because it does not execute.
Note
For all current program development, it is recommended that you use WHEN ERROR constructs for user-written error handlers. Mixing WHEN ERROR constructs and ON ERROR statements within the same program is not recommended. The ON ERROR statements are supported for compatibility with other versions of BASIC available from VSI. It is important to note that all of these statements are illegal within a protected region, or an attached or detached handler.
The ON ERROR statements are documented in the VSI BASIC Reference Manual. This section briefly describes the main features of the ON ERROR statements.
The ON ERROR statements can be used to transfer control to a labeled block of error handling code. If you have executed an ON ERROR statement and an error occurs, the ON ERROR statement immediately transfers control to the label or line number that starts the error handling code. Otherwise, the ON ERROR statement specifies the branch to be taken in the event of an error.
- The ON ERROR GOTO 0 statement reverts control to VSI BASIC for OpenVMS default error handling in one of two ways:
If an error is pending, execution of the ON ERROR GOTO 0 statement returns control to the VSI BASIC for OpenVMS error handler immediately.
If no error is pending, an ON ERROR GOTO 0 statement disables your current error handler. The VSI BASIC for OpenVMS error handler handles all subsequent errors until another ON ERROR statement is executed, unless an error occurs in a WHEN ERROR protected region.
ON ERROR GOTO target
The ON ERROR GOTO target statement reverts control to the target when subsequent errors occur that are not handled by WHEN block handlers.
ON ERROR GO BACK
The ON ERROR GO BACK statement transfers control to the calling program's error handler if an error occurs in the subprogram or DEF function. If you use ON ERROR GO BACK in a PROGRAM unit (outside of a DEF function) and no other outer protected region exists, it is equivalent to ON ERROR GOTO 0 and VSI BASIC for OpenVMS default error handling is in effect. With ON ERROR GO BACK, if an error occurs in the execution of a function or subprogram, the error is passed to either the error handler of the surrounding program module (in the case of a DEF function definition) or to the error handler of the calling program (in the case of a separately compiled subprogram).
An error handler in the DEF function does not permanently override an error handler in the main program. VSI BASIC for OpenVMS saves the error handler in the main program when you transfer into a DEF, and restores it when you return.
5 ON ERROR GOTO Error_handler . . . Error_handler: !Trap end of file on device IF ERR = 11 THEN RESUME 1000 ELSE ON ERROR GO BACK END IF
The ON ERROR GOTO statement remains in effect after your program successfully handles an error. When the system signals another error, control once again transfers to the specified error handler.
RESUME [target]
ON ERROR GOTO 0
ON ERROR GO BACK
If none of these statements is present, the VSI BASIC for OpenVMS error handler aborts your program with the fatal error “Error trap needs RESUME” as soon as an END, END SUB, END DEF, END FUNCTION, END PROGRAM, or END PICTURE statement is encountered. The RESUME statement, like the RETRY and CONTINUE statements, clears the error condition.
If you resume execution at a multistatement line, execution begins at the first statement after the line number or label—not necessarily at the statement that generated the error.
If an entire loop block is associated with a single line number or label and an error occurs within the loop, RESUME with no target transfers control to the statement immediately after the FOR, WHILE, or UNTIL statement, not to the line number or label.
For more information about the RESUME statement, see the VSI BASIC Reference Manual.
Control passes to the handler associated with the innermost WHEN ERROR block.
If protected regions are nested, the pending error is handled by the handler associated with the next outer WHEN ERROR block.
When no outer protected regions can handle the error, and if an ON ERROR statement is in effect, control transfers to the target of the next outer ON ERROR statement (if one is present).
If no outer handler is available or can handle the error, the error is passed to VSI BASIC for OpenVMS default error handling. Default error handling is equivalent to ON ERROR GOTO 0 for main procedures, and ON ERROR GO BACK for SUBs, FUNCTIONs, and DEFs.
For information about specific run-time errors, see Appendix B, Run-Time Messages.
Chapter 16. Compiler Directives
Compiler directives are instructions that tell VSI BASIC for OpenVMS to perform certain operations as it translates a source program. This chapter describes how to control program compilation using compiler directives.
16.1. Overview of Compiler Directives
Place program titles and subtitles in the header that appears on each page of the listing file.
Place a program version identification string in both the listing file and the object module.
Start or stop the inclusion of listing information for selected parts of a program.
Start or stop the inclusion of cross-reference information for selected parts of a program.
Include VSI BASIC for OpenVMS code from another source file or a text library.
Include CDD/Repository record definitions in a VSI BASIC for OpenVMS program.
Record dependency relationships in CDD/Repository.
Display a message at compile time.
Conditionally compile parts of a program.
Terminate compilation.
Directives must begin with a percent sign (%).
Directives can be preceded by an optional line number.
Directives must be the only text on the line (except for %IF-%THEN-%ELSE-%END %IF).
Directives cannot appear within a quoted string.
Directives cannot follow an END, END SUB, or END FUNCTION statement.
16.2. Controlling the Compilation Listing
%TITLE places a title string on the first line of the listing header.
%SBTTL places a subtitle string on the second line of the listing header.
%IDENT places an identification string on the second line of the listing header and within the object module.
%PAGE causes BASIC to skip to top-of-form in the output listing.
%NOLIST causes BASIC to stop accumulating information for the output listing.
%LIST causes BASIC to resume accumulating information for the output listing.
%NOCROSS causes BASIC to stop accumulating cross-reference information for the output listing.
%CROSS causes BASIC to resume accumulating cross-reference information for the output listing.
These directives are described in the following sections.
The listing control directives have no effect if no source program listing is being produced. Similarly, the %CROSS and %NOCROSS directives have no effect if no cross-reference listing is being produced. However, the %IDENT directive places the specified text in the object module whether or not a listing is produced.
16.2.1. %TITLE and %SBTTL Directives
The %TITLE directive lets you specify a line of text that appears on the first line of every page in the compilation listing. This text line is a quoted string of up to 31 characters and normally contains the source program title and other information.
If the %TITLE directive is the first source text in a module, then the quoted string appears in the first line of every page of the compilation listing; otherwise, the quoted string appears in the first line of every subsequent page in the compilation listing. That is, if BASIC encounters a %TITLE directive after it has begun creating a page in the output listing, the title information will not appear on that page. Rather, it appears on all of the following pages until it encounters another %TITLE directive.
%TITLE "File OPEN Subprogram -- Author Hugh Ristics" SUB FILSUB (STRING F_NAME)
The %SBTTL directive lets you specify a line of text that appears on the second line of every page in the compilation listing (beneath the title). If BASIC encounters a %SBTTL directive after it has begun creating a page in the output listing, the subtitle information will not appear on that page. Rather, it appears on all following pages until it encounters another %SBTTL or %TITLE directive. If you want the subtitle to appear on the first page, the %SBTTL directive must appear directly after the %TITLE directive.
Any number of %SBTTL directives can appear in a source file; thus, you can use subtitle text to identify parts of the source program. As in %TITLE, the text you use in %SBTTL must be a quoted string not exceeding 31 characters. Note, however, that subtitle information appears on listing pages that contain the actual source code.
%TITLE "Payroll Program" %SBTTL "Constant Declarations" . . . %SBTTL "Subroutines" . . . %SBTTL "Error Handler" . . .
You can use multiple %TITLE directives in a single source file; however, whenever BASIC encounters a %TITLE directive, the %SBTTL information is set to the null string. Therefore, if you want to display subtitle information, each new %TITLE directive should be accompanied by a new %SBTTL directive.
16.2.2. %IDENT Directive
The %IDENT directive identifies the version of a program module. The identification text must be a quoted string of up to 31 characters. The information contained within the identification text appears in the listing file and the object module. Thus, the map file created by the OpenVMS Linker also contains this information.
%IDENT "V5.3" SUB PAY . . .
If your source module contains multiple %IDENT directives, BASIC signals a warning and uses the version specified in the first %IDENT directive.
16.2.3. %PAGE Directive
%TITLE "Payroll Program" %SBTTL "Constant Declarations" . . . %PAGE %SBTTL "Subroutines" . . . %PAGE %SBTTL "Error Handler" . . .
16.2.4. %LIST and %NOLIST Directives
%LIST and %NOLIST are complementary directives. The %LIST directive causes BASIC to resume adding information to the listing file, while the %NOLIST directive causes BASIC to stop adding information to the listing file. Therefore, you can control which parts of the source program are to be listed.
%TITLE "Payroll Program" %SBTTL "Constant Declarations" . . . %NOLIST . . . %LIST . . . %PAGE %SBTTL "Subroutines" . . . %PAGE %SBTTL "Error Handler" . . .
If you have not requested the creation of a compilation listing, the %LIST and %NOLIST directives have no effect.
If a program line contains a syntax error, BASIC overrides the %NOLIST directive for that line and produces the normal error diagnostics in the listing file.
16.2.5. %CROSS and %NOCROSS Directives
The %CROSS and %NOCROSS directives are complementary. The %CROSS directive causes BASIC to resume adding cross-reference information, while the %NOCROSS directive causes BASIC to stop adding cross-reference information to the listing file. Therefore, you can specify that only certain parts of the source program are to be cross-referenced.
%TITLE "Payroll Program" %SBTTL "Constant Declarations" . . . %NOCROSS . . . %CROSS . . . %PAGE %SBTTL "Subroutines" . . . %PAGE %SBTTL "Error Handler" . . .
If you have not requested the creation of a cross-reference listing, the %CROSS and %NOCROSS directives have no effect.
16.3. Accessing External Source Files
The %INCLUDE directive lets you access BASIC source text from a file into the source program. The %INCLUDE directive also lets you access record definitions in CDD/Repository as well as access source text from a text library. The line on which a %INCLUDE directive resides can be continued, but cannot contain any other directives or statements.
%INCLUDE "KEN.BAS"
%INCLUDE %FROM %CDD "CDD$TOP.EMPLOYEE"
See the CDD/Repository CDO Reference Manual for more information about CDD/Repository.
If you are including source text from a text library, you must supply the name of the text module you wish to include as well as the name of the library where the module resides. If you do not specify a library name, BASIC uses the default library, BASIC$LIBRARY. Moreover, if you do not specify a directory name or file type, BASIC uses the default device and the file type .TLB. If the BASIC$LIBRARY logical name is undefined, SYS$LIBRARY:BASIC$STARLET.TLB is used. The default file specification is BASIC.TLB.
%INCLUDE "DMB_TEST" %FROM %LIBRARY "SYS$LIBRARY:BASIC_LIB.TLB"
BASIC supplies the text library BASIC$STARLET located in SYS$LIBRARY. This text library contains condition codes and other symbols defined in the system object and shareable image libraries. Using the definitions from BASIC$STARLET allows you to reference condition codes and other system-defined symbols as local, rather than global symbols.
To create your own text libraries using the OpenVMS Librarian utility, see the VSI OpenVMS Librarian Utility Manual.
All file specifications, CDD/Repository path specifications, text modules, and library specifications must be string literals enclosed in quotation marks.
The source files accessed with %INCLUDE cannot contain line numbers. This requirement means that all statements in the accessed file are associated with the BASIC line containing the %INCLUDE directive if line numbers are being used. Therefore, if you are using line numbers, a %INCLUDE directive cannot appear before the first line number in a source program. A file accessed by %INCLUDE can itself contain a %INCLUDE directive.
When a program is compiled, BASIC inserts the included text at the point at which it encounters the %INCLUDE directive. The compilation listing identifies any text obtained from an included file by placing a mnemonic in the first character position of the line in which the text appears. “I n” specifies text that was either accessed from a source file or from a text library, and “C n” specifies a record definition that was accessed from CDD/Repository. Both the I and the C tell you that the text was accessed with the %INCLUDE directive, and n tells you the nesting level of the included text.
The %INCLUDE directive is useful when you want to share code among multiple program modules. To do this, you must first create a file that contains the shareable code, then include that file in all the modules that require it. Thus, you reduce the chance of a typographical error.
You can prevent the %INCLUDE file code from appearing in the compilation listing by using the BASIC command qualifier /SHOW=NOINCLUDE or /SHOW=NOCDD_DEFINITIONS. For text files and text library modules, use the qualifier /SHOW=NOINCLUDE. For CDD/Repository definitions, use the qualifier /SHOW=NOCDD_DEFINITIONS.
16.4. Controlling Compilation
BASIC lets you control the compilation of a program by creating and testing lexical constants. You create and assign values to lexical constants with the %LET directive. These constants are always LONG integers.
Supply different values for program variables and constants.
Skip over part of a program.
Abort a compilation.
Include BASIC source code from another file.
Display informational messages during the compilation.
BASIC also supplies the lexical built-in function %VARIANT that can be used to conditionally control compilation.
Lexical constants and expressions (%LET directive)
%VARIANT
%ABORT
%PRINT
%IF-%THEN-%ELSE-%END %IF
16.4.1. %LET Directive
The %LET directive creates and assigns values to lexical constants. Lexical constants are always LONG integers. These constants control the execution of the %IF-%THEN-%ELSE-%END %IF directive.
All lexical constants must be created with %LET before they can be used in a %IF-%THEN-%ELSE-%END %IF directive, and each lexical constant must be created with a separate %LET directive. All lexical constant names must also be preceded by a percent sign and cannot end with a dollar sign or percent sign.
A lexical constant
An integer literal
A lexical built-in function (%VARIANT)
Any combination of these, separated by logical, relational, or arithmetic operators
%LET %debug_on = 0%
See Section 16.4.5, “%IF-%THEN-%ELSE-%END %IF Directive” for an example of using %LET with %IF-%THEN-%ELSE.
16.4.2. %VARIANT Directive
The SET VARIANT command when a program is compiled in the VAX BASIC Environment
The /VARIANT qualifier when a program is compiled from the system command level or from within the VAX BASIC Environment
The %VARIANT function returns the variant value set with either of these methods.
The default value for the %VARIANT function is zero. See Section 16.4.5, “%IF-%THEN-%ELSE-%END %IF Directive” for an example of controlling compilation with %VARIANT.
16.4.3. %ABORT Directive
The %ABORT directive terminates the compilation and displays a message you provide.
The text must be a quoted string literal. This information is displayed to SYS$ERROR and in the compilation listing if one is being created. BASIC stops the compilation and terminates the listing file as soon as it encounters a %ABORT directive, and so BASIC does not perform syntax checking on the remainder of the program. See Section 16.4.5, “%IF-%THEN-%ELSE-%END %IF Directive” for an example of using %ABORT.
16.4.4. %PRINT Directive
The %PRINT directive allows you to insert a message into your source code that the BASIC compiler displays at compile time.
The text must be a quoted string literal. This information is displayed to SYS$ERROR and in the compilation listing if one is being created. BASIC prints the message specified as soon as it encounters a %PRINT directive. See Section 16.4.5, “%IF-%THEN-%ELSE-%END %IF Directive” for an example of using %PRINT.
16.4.5. %IF-%THEN-%ELSE-%END %IF Directive
Compile source text
Execute another compiler directive
This directive differs from all others in that it can appear anywhere in a program where a space is allowed, except within a quoted string.
You must include %END %IF. Otherwise, the rest of the source program becomes part of the %THEN or %ELSE clause. You must also include a lexical expression and some BASIC source code.
The truth or falsity of the lexical expression determines whether BASIC compiles the source code in the %THEN clause or the %ELSE clause. If the lexical expression is true, BASIC does not compile the source code in the %ELSE clause. If the lexical expression is false, BASIC does not compile the source code in the %THEN clause. However, VSI BASIC for OpenVMS does check for lexical errors (such as illegally formed numeric constants) in the uncompiled block of code. If an uncompiled block of code contains a lexical error, VSI BASIC for OpenVMS signals an error.
Even though VSI BASIC for OpenVMS compiles only one block of code in an %IF-%THEN-%ELSE-%END-%IF directive, you cannot use the same line number in both a %THEN block and an %ELSE block. If you specify the same line number, the first occurrence of the line number is replaced by the second when the program is compiled.
%IF (%VARIANT = 2%) %THEN DECLARE LONG int_array(100) %ELSE DECLARE WORD int_array(100) %END %IF
This directive allows for two possibilities. If you compile this program with a /VARIANT=2 qualifier, then BASIC creates an array of longword integers. If you compile this program with any other variant value, BASIC creates an array of word integers.
DECLARE %IF (%VARIANT=2%) %THEN LONG %ELSE WORD %END %IF int_array(100)
%LET %my_constant = 8% %IF ( (%my_constant + %VARIANT) >= 10% )%THEN %ABORT "Cannot compile with VARIANT >= 2" %ELSE %PRINT "Successful Compilation" %END %IF
The compilation listing shows you which clause was actually compiled.
16.5. Record Dependency Relationships in CDD/Repository
By using the %INCLUDE %FROM %CDD or the %REPORT %DEPENDENCY directives in conjunction with the /DEPENDENCY_DATA qualifier in the BASIC command, you can record dependency relationships in a CDO dictionary between a compiled module entity and included records or other referenced dictionary entities.
See Chapter 21, Using CDD/Repository with BASIC for more information about record dependency relationships.
Chapter 17. Data Representation
This chapter describes how VSI BASIC represents data stored in memory.
The following sections discuss four types of data representation: integer, float, decimal, and string.
17.1. Integer Format
There are four ways in which integer data can be represented, depending on the size of the data to be stored: byte, word, longword, and quadword. Negative integer values are stored in two's complement format. The following sections describe each of these formats.
17.1.1. Byte-Length Integer Format
Byte-length integers are in the range -128 to 127 and are stored as 1 byte (8 bits), starting on an arbitrary byte boundary. Bits are labeled from the right, 0 to 7, as in Figure 17.1, “Byte-Length Integer Format”.
17.1.2. Word-Length Integer Format
Word-length integers are in the range -32768 to 32767 and are stored as two contiguous bytes, starting on an arbitrary byte boundary. Bits are labeled from the right, 0 to 15, as in Figure 17.2, “Word-Length Integer Format”.
17.1.3. Longword Integer Format
Longword integers are stored as four contiguous bytes, starting on an arbitrary byte boundary. Values are in the range -2147483648 to 2147483647. See Figure 17.3, “Longword Integer Format”.
17.1.4. Quadword Integer Format
Quadword integers are stored as eight contiguous bytes, starting on an arbitrary byte boundary. Values are in the range -9223372036854775808 to 9223372036854775807. See Figure 17.4, “Quadword Integer Format”.
BYTE -128% WORD -32768% LONG -2147483648% QUAD -9223372036854775808%
BYTE -127% - 1% WORD -32767% - 1% LONG -2147483647% - 1% QUAD -9223372036854775807% - 1%
17.2. Real Number Format
Real numbers, like integers, can be represented in varying formats, depending on the size of the data to be stored. These formats include SINGLE floating-point, DOUBLE floating-point, GFLOAT floating-point, SFLOAT floating-point, TFLOAT floating-point, XFLOAT floating-point, and packed DECIMAL format. The following sections describe each of these formats.
17.2.1. SINGLE Floating-Point Number Format (F_floating)
F_floating (single-precision) floating-point numbers are stored as four contiguous bytes, starting on an arbitrary byte boundary. Bits are labeled from the right, 0 to 31.
The format for single-precision is sign magnitude, with bit 15 the sign bit, bits 14 to 7 an excess-128 binary exponent, and bits 6 to 0 and 31 to 16 a normalized 24-bit fraction with the redundant, most significant fraction bit not represented. See Figure 17.5, “Single-Precision Real Number Format” for the format. The 8-bit exponent field encodes the values from 0 to 255, inclusively.
An exponent value of 0 together with a sign bit of 0 indicates that the F_floating number has a value of 0. Exponent values from 1 to 255 indicate true binary exponents of -127 to 127. An exponent value of 0, together with a sign bit of 1, is taken as reserved. (Floating-point instructions processing a reserved operand take a reserved operand fault.) The magnitude of an F_floating number is in the approximate range .29 * 10-38 to 1.7 * 1038. The precision of an F_floating number is approximately one part in 223 (approximately 7 decimal digits).
17.2.2. DOUBLE Floating-Point Number Format (D_floating)
Double-precision real number format consists of eight contiguous bytes, starting on an arbitrary byte boundary. Bits are labeled from the right, 0 to 63, as in Figure 17.6, “Double-Precision Real Number Format”. The form of a D_floating number is identical to the F_floating form, except for an additional 32 low-significance fraction bits. Within the fraction, bits increase in significance from 48 to 63, 32 to 47, 16 to 31, and 0 to 6. The exponent conventions and approximate range of values are the same for both D_floating and F_floating numbers. The precision of a D_floating number is approximately one part in 255 (approximately 16 decimal digits).
Note
Because most floating-point values cannot be represented exactly in binary, they are susceptible to rounding. I64 BASIC and the Itanium hardware use T_floating representation in place of D_floating representation. Alpha BASIC and the Alpha system hardware use G_floating representation in place of the D_floating representation. Thus, the behavior of floating-point computations and comparisons can be different from what you expect.
17.2.3. GFLOAT Floating-Point Number Format (G_floating)
The G_floating floating-point number format consists of eight contiguous bytes, starting on an arbitrary byte boundary, as shown in Figure 17.7, “SGFLOAT Floating-Point Number Format”. Bits are labeled from the right, 0 to 63. The form of a G_floating number is sign magnitude with bit 15 the sign bit, bits 14 to 4 an excess-1024 binary exponent, and bits 3 to 0 and 63 to 16 a normalized 53-bit fraction with the redundant most significant fraction bit not represented.
Within the fraction, bits increase in significance from 48 to 63, 32 to 47, 16 to 31, and 0 to 3. The 11-bit exponent field encodes the values 0 to 2047.
17.2.4. SFLOAT Floating-Point Number Format (S_floating)
The S_floating floating-point number format consists of four contiguous bytes, starting on an arbitrary byte boundary, as shown in Figure 17.8, “SFLOAT Floating-Point Number Format”. Bits are labeled from the right, 0 to 31. The form of an S_floating number is sign magnitude with bit 31 the sign bit, bits 30 to 23 an excess-127 binary exponent, and bits 22 to 0 a normalized 24-bit fraction with the redundant most significant fraction bit not represented unless the exponent is 0. If the exponent is 0, a nonzero fraction represents an unnormalized 23-bit fraction.
An exponent value of 0 together with a fraction value of 0 and a sign bit of 0 indicates that the S_floating number value is 0. Exponent values from 1 to 254 indicate true binary exponents from -127 to 127. The value of an S_floating number is in the approximate range 1.175 * 10-38 to 3.402 * 1038; the precision is approximately one part in 223 (approximately 7 decimal digits). Note that S_floating format provides approximately the same range and precision as F_floating format.
17.2.5. TFLOAT Floating-Point Number Format (T_floating)
The T_floating floating-point number format consists of eight contiguous bytes, starting on an arbitrary byte boundary, as shown in Figure 17.9, “TFLOAT Floating-Point Number Format”. Bits are labeled from the right, 0 to 63. The form of a T_floating number is sign magnitude with bit 63 the sign bit, bits 62 to 52 an excess-1023 binary exponent, and bits 51 to 0 a normalized 53-bit fraction with the redundant most significant fraction bit not represented unless the exponent is 0. If the exponent is 0, a nonzero fraction represents an unnormalized 52-bit fraction.
An exponent value of 0 together with a fraction value of 0 and a sign bit of 0 indicates that the T_floating number value is 0. Exponent values from 1 to 2046 indicate true binary exponents from -1023 to 1023. The value of a T_floating number is in the approximate range 2.225 * 10-308 to 1.797 * 10308; the precision is approximately one part in 252 (approximately 15 decimal digits). Note that T_floating format provides approximately the same range and precision as G_floating format.
17.2.6. XFLOAT Floating-Point Number Format (X_floating)
The X_floating floating-point number format consists of sixteen contiguous bytes, starting on an arbitrary byte boundary, as shown in Figure 17.10, “XFLOAT Floating-Point Number Format”. Bits are labeled from the right, 0 to 127. The form of an X_floating number is sign magnitude with bit 127 the sign bit, bits 126 to 112 an excess-16383 binary exponent, and bits 111 to 0 a normalized 113-bit fraction with the redundant most significant fraction bit not represented unless the exponent is 0. If the exponent is 0, a nonzero fraction represents an unnormalized 112-bit fraction.
An exponent value of 0 together with a fraction value of 0 and a sign bit of 0 indicates that the X_floating number value is 0. Exponent values from 1 to 32766 indicate true binary exponents from -16383 to 16383. The value of an X_floating number is in the approximate range 3.362 * 10-4932 to 1.189 * 104932; the precision is approximately one part in 2112 (approximately 33 decimal digits). Note that X_floating format provides approximately the same range and precision as H_floating format.
17.3. Packed Decimal Number Format
Digit or Sign |
Decimal |
Hexadecimal |
---|---|---|
0 |
0 |
0 |
1 |
1 |
1 |
2 |
2 |
2 |
3 |
3 |
3 |
4 |
4 |
4 |
5 |
5 |
5 |
6 |
6 |
6 |
7 |
7 |
7 |
8 |
8 |
8 |
9 |
9 |
9 |
+ |
10,12,14, or 15 |
A,C,E, or F |
– |
11 or 13 |
B or D |
Despite the options, the preferred sign representation is 12 for positive and 13 for negative. The length L is the number of digits in the packed decimal string (not counting the sign) and must be in the range 1 to 31. If the number of digits is odd, the digits and the sign fit into ((L/2) + 1) bytes; when the number of digits is even, an extra 0 digit must appear in the high nibble (bits 7 to 4) of the first byte.
The address A of the string specifies the byte of the string containing the most significant digit in its high nibble. Digits of decreasing significance are assigned to increasing byte addresses and from high nibble to low nibble within a byte.
Note that the decimal point is specified by the descriptor for the packed decimal string. See Section 17.6, “Decimal Scalar String Descriptor (Packed Decimal String Descriptor)” for more information about packed decimal string descriptions.
17.4. String and Array Descriptor Format
A descriptor is an OpenVMS data structure that describes how to access data in memory. A descriptor can also pass information about a parameter with that parameter. The following sections describe the formats for fixed-length and dynamic string descriptors.
17.4.1. Fixed-Length String Descriptor Format
A fixed-length string descriptor consists of two longwords.
The first word of the first longword contains a value equal to the string's length. The third byte contains 14 (0E hexadecimal—the OpenVMS code describing an ASCII character string). The fourth byte contains 1.
The second longword is a pointer containing the address of the string's first byte. See Figure 17.11, “Fixed-Length String Descriptor Format”. For more information, see the OpenVMS Calling Standard.
17.4.2. Dynamic String Descriptor Format
A dynamic string descriptor consists of two longwords.
The first word of the first longword contains a value equal to the string's length. The third byte contains 14 (0E hexadecimal—the OpenVMS code describing an ASCII character string). The fourth byte contains 2.
The second longword is a pointer containing the address of the string's first character. See Figure 17.12, “Dynamic String Descriptor Format”. For more information, see the OpenVMS Calling Standard.
17.5. Array Descriptors
VSI BASIC for OpenVMS creates DSC$K_CLASS_NCA, a noncontiguous class array descriptor. For more information, see the OpenVMS Calling Standard.
17.6. Decimal Scalar String Descriptor (Packed Decimal String Descriptor)
A single descriptor form gives decimal size and scaling information for both scalar data and simple strings. See Figure 17.13, “Decimal Scalar String Descriptor” for more information.
For packed decimal strings, the length field contains the number of 4-bit digits (not including the sign). The pointer field contains the address of the first byte in the packed decimal string. The scale field contains a signed power-of-ten multiplier to convert the internal form to the external form. For example, if the internal number is 123 and the scale field is +1, then the external number is 1230.
Part III. Using VSI BASIC for OpenVMS Features on OpenVMS Systems
Part III, “Using VSI BASIC for OpenVMS Features on OpenVMS Systems” describes BASIC features available on OpenVMS systems including advanced file input and output, libraries and shareable images, and error messages.
Chapter 18. Advanced File Input and Output
RMS I/O to ANSI magnetic tapes
Device-specific I/O to magnetic tapes (including TK50 devices), disks, and unit record devices
I/O to mailboxes
Network I/O
OPEN "MTA2:" FOR OUTPUT AS FILE #1 OPEN "MTA1:PARTS.DAT" FOR INPUT AS FILE #2, SEQUENTIAL
Because the file specification in the first line does not contain a file name, the OPEN statement opens the tape drive for device-specific I/O. The second line opens an ANSI-format tape file using RMS because a file name is part of the file specification.
The following sections describe both I/O to ANSI-format magnetic tapes and device-specific I/O to magnetic tape, unit record, and disk devices.
For more information about I/O to RMS disk files, see Chapter 13, File Input and Output.
18.1. RMS I/O to Magnetic Tape
VSI BASIC for OpenVMS supports I/O to ANSI-formatted magnetic tapes. When performing I/O to ANSI-formatted magnetic tapes, you can read or write to only one file on a magnetic tape at a time, and the files are not available to other users. ANSI tape files are RMS sequential files.
18.1.1. Allocating and Mounting a Tape
$
ALLOCATE MT1:
$
MOUNT/DENSITY=1600 MT1: VOL001 TAPE
When mounting a TK50, you cannot specify a density.
$
MOUNT/DENSITY=1600/BLOCKSIZE=128 MT1: VOL020 TAPE
Alternatively, you can use the $MOUNT system service to mount tapes.
18.1.2. Opening a Tape File for Output
OPEN "MT1:PARTS.DAT" FOR OUTPUT AS FILE #2%, SEQUENTIAL FIXED, & RECORDSIZE 256%, BLOCKSIZE 4%
Note
Every record in an ANSI D formatted file is prefixed by a 4-byte header giving the record length in decimal ASCII digits. The length includes the 4-byte header. VSI BASIC for OpenVMS adds the 4-byte header to the record size when calculating block size. The header is transparent to your program.
If you do not specify a block size, VSI BASIC for OpenVMS defaults to one record per block. For small records, this can be inefficient; the tape will contain many interrecord gaps.
18.1.3. Opening a Tape File for Input
100 OPEN "TAPE:PAYROLL.DAT" FOR INPUT AS FILE #4% ,ACCESS READ
18.1.4. Positioning a Tape
Specifying NOREWIND when you create a file positions the tape at the logical end-of-tape and leaves the unit open for writing. If you omit NOREWIND, you start writing at the beginning of the tape (BOT), logically deleting all subsequent files.
Specifying NOREWIND when you open an existing file starts a search for the file at the current position. The search continues to the logical end-of-tape. If the record is not found, VSI BASIC for OpenVMS rewinds and continues the search until reaching the logical end-of-tape again. Omitting NOREWIND tells VSI BASIC for OpenVMS to rewind the tape and search for the file name until reaching the end-of-tape. In either case, you receive an error message if the file does not exist.
OPEN "MT1:PAYROL.DAT" FOR OUTPUT AS FILE #1% & ,ORGANIZATION SEQUENTIAL, NOREWIND
Note that you cannot specify REWIND; to avoid rewinding the tape, omit the NOREWIND keyword.
OPEN "MT0:TEST.DAT" FOR OUTPUT AS FILE #2, & SEQUENTIAL FIXED, RECORDSIZE 20% B$ = "" WHILE B$ <> "NO" LINPUT "Name"; A$ MOVE TO #2, A$ = 20 PUT #2 LINPUT "Write another record"; B$ NEXT CLOSE #2 END
RECORDSIZE 60%
This clause specifies a record length and a record buffer size of 60 bytes. You can specify a record length from 18 to 8192 bytes. The default is 132 bytes.
If you specify a MAP clause and no RECORDSIZE clause, then the record size is the size of the map.
RECORDSIZE 60%, BLOCKSIZE 4%
These clauses specify a logical record length of 60 bytes and a physical tape record size of 240 bytes (60 * 4). You specify BLOCKSIZE as an integer number of records. RMS rounds the resulting value to the next multiple of four. The total I/O buffer length cannot exceed 8192 bytes. The default is a buffer (tape block) containing one record.
To write true variable-length records, use the COUNT clause with the PUT statement to specify the number of bytes of data written to the file. Without COUNT, all records equal the length specified by the RECORDSIZE clause when you opened the file.
18.1.6. Reading Records from a File
OPEN "MT0:TEST.DAT" FOR INPUT AS FILE #5%, & ORGANIZATION SEQUENTIAL FIXED, RECORDSIZE 20%, & BLOCKSIZE 4%, ACCESS READ B$ = "" WHILE B$ <> "NO" GET #5 MOVE FROM #5, A$ = 20 PRINT A$ LINPUT "Do you want another record"; B$ NEXT CLOSE #5 END
18.1.7. Controlling Tape Output Format
Magnetic tape physical records range from 18 to 8192 bytes. With RMS tapes, you can optionally specify this size in the BLOCKSIZE clause as a positive integer indicating the number of records in each block. VSI BASIC for OpenVMS then calculates the actual size in bytes. Thus, a fixed-length file on tape with 126 byte records can have a block size from 1 to 64, inclusive. The default is 126 bytes (one record per block).
OPEN "MT0:[SMITH]TEST.SEQ" FOR OUTPUT AS FILE #12% & ,ORGANIZATION SEQUENTIAL FIXED, RECORDSIZE 90% & ,BLOCKSIZE 12%
Through RMS, VSI BASIC for OpenVMS controls the blocking and deblocking of records. RMS checks each PUT operation to see if the specified record fits in the tape block. If it does not, RMS fills the rest of the block with circumflexes (blanks) and starts the record in a new block. Records cannot span blocks in magnetic tape files.
MAP (XXX) NA.ME$ = 5%, address$ = 20% OPEN "MTO:FILE.DAT" FOR INPUT AS FILE #4%, & SEQUENTIAL FIXED, MAP XXX, ACCESS READ NA.ME$ = "" GET #4 UNTIL NA.ME$ - "JONES" PRINT NA.ME$; "LIVES AT "; address$ CLOSE #4 END
18.1.8. Rewinding a Tape
OPEN "MTO:FTF.DAT" FOR INPUT AS FILE #2%, ACCESS READ GET #2% . . . RESTORE #2% GET #2%
You cannot rewind past the beginning of the currently open file.
18.1.9. Closing a File
CLOSE #6%
Writes the file trailer labels and two end-of-file marks following the last record
Backspaces over the last end-of-file mark
VSI BASIC for OpenVMS does not rewind the tape.
18.2. Device-Specific I/O
Device-specific I/O lets you perform I/O directly to a device. The following sections describe device-specific I/O to unit record devices, tapes, and disks.
18.2.1. Device-Specific I/O to Unit Record Devices
$
ALLOCATE CR1:
MAP (DNG) A% = 80% OPEN "CR1:" FOR INPUT AS FILE #1%, ACCESS READ, MAP DNG GET #1%
VSI BASIC for OpenVMS treats the device as a file, and data is read from the card reader as a series of fixed-length records.
18.2.2. Device-Specific I/O to Magnetic Tape Devices
When performing device-specific I/O to a tape drive, you open the physical device and transfer data between the tape and your program. GET and PUT statements perform read and write operations. UPDATE and DELETE statements are invalid when you perform device-specific I/O.
18.2.2.1. Allocating and Mounting a Tape
$
ALLOCATE MT1:
$
MOUNT/FOREIGN MT1:
$
MOUNT/FOREIGN/BLOCKSIZE=1024/DENSITY=1600 MT1:
When reading a foreign tape, you must make sure the /BLOCKSIZE qualifier has a value at least as large as the largest record on the tape.
18.2.2.2. Opening a Tape File for Output
PEN "MT1:" FOR OUTPUT AS FILE #1%, & ORGANIZATION SEQUENTIAL VARIABLE
18.2.2.3. Opening a Tape File for Input
OPEN "MT2:" AS FILE #2%
Depending on how you access records, there are two ways to open a foreign magnetic tape. If your program uses dynamic buffering and MOVE statements, open the file with no RECORDSIZE clause. RMS will provide the correct buffer size for VSI BASIC for OpenVMS. Do not specify a BLOCKSIZE value or ORGANIZATION clause with the OPEN statement.
If your program uses MAP and REMAP statements, but you do not know how long the records are, specify a MAP that is as large as the value you specified for the BLOCKSIZE qualifier when mounting the tape. Do not specify a BLOCKSIZE value or ORGANIZATION clause with the OPEN statement.
When processing records, each GET operation will read one physical record whose size is returned in RECOUNT. If you are using a map only, the first n bytes ( n is the value returned in RECOUNT) are valid.
18.2.2.4. Writing Records to a File
OPEN "MT0:" FOR OUTPUT AS FILE #9%, & SEQUENTIAL VARIABLE INPUT "NAME";NA.ME$ MOVE TO #9%, NA.ME$ PUT #9%
The last line writes the contents of the record buffer to the device. Successive PUT operations write successive records.
OPEN "MT0:" FOR INPUT AS FILE #1%, RECORDSIZE 900%
PUT #6%, COUNT 56%
18.2.2.5. Reading Records from a File
OPEN "MT1:" FOR INPUT AS FILE #1%, ACCESS READ GET #1% MOVE FROM #1%, A$ = RECOUNT PRINT A$ RESTORE #1% CLOSE #1%
18.2.2.6. Rewinding a Tape
OPEN "MT1:" FOR OUTPUT AS FILE #2%, ACCESS READ . . . PUT #2% RESTORE #2% INPUT "NEXT RECORD"; NXTRECBB%
If you rewind a tape opened without ACCESS READ before closing it, you erase all data written before the RESTORE operation.
18.2.2.7. Closing a Tape
CLOSE #12%
Writes file trailer labels and two end-of-file marks following the last record
Backspaces over the last end-of-file mark
The tape is not rewound unless you specified RESTORE in your program.
18.2.3. Device-Specific I/O to Disks
When performing device-specific I/O to disks, you write and read data with PUT and GET statements. The data must fit in 512-byte blocks, and you must do your own blocking and deblocking with MAP/REMAP or MOVE statements. Note that, when accessing disks with device-specific I/O operations, you are performing logical I/O. Because of this, you should be careful not to overwrite block number zero, which is often the disk's boot block. You must have LOG_IO privileges to perform these operations.
The following sections describe device-specific I/O to disks.
18.2.3.1. Assigning and Mounting a Disk
$
ALLOCATE DUA3:
$
MOUNT/FOREIGN DUA3:
You can then open the disk for input or output.
18.2.3.2. Opening a Disk File for Output
OPEN "DUA3:" FOR OUTPUT AS FILE #2%, SEQUENTIAL FIXED, & RECORDSIZE=512
You can then write data to the disk.
The record size determined by the MAP or RECORDSIZE clause must be an integer multiple of 512 bytes.
18.2.3.3. Opening a Disk File for Input
OPEN "DUA1:" FOR INPUT AS FILE #4%, SEQUENTIAL FIXED, & RECORDSIZE=512
You can then read data from the disk.
The record size determined by the MAP or RECORDSIZE clause must be an integer multiple of 512 bytes. The default is 512.
Specify ACCESS READ in the OPEN statement if you only plan to read from the disk.
18.2.3.4. Writing Records to a Disk File
INPUT "HOW MANY RECORDS TO WRITE"; J% OPEN "DBB2: FOR OUTPUT AS FILE #2%, SEQUENTIAL FIXED, & RECORDSIZE=512 FOR K% = 1% TO J% FOR I% = 0% TO 7% INPUT "NAME OF BOOK"; BOOK_NAME$ INPUT "RETRIEVAL NUMBER"; RET_NUM% INPUT "SUBJECT AREA"; SUBJ$ MOVE TO #2%, FILL$ = I% * 64%, BOOK_NAME$, RET_NUM%, SUBJ$ NEXT I% PUT #2% NEXT K% CLOSE #2
When you write records, VSI BASIC for OpenVMS does not prefix the records with any count bytes.
18.2.3.5. Reading Records from a Disk File
You read data by defining a record buffer and reading the data from the device with GET statements. After the data has been retrieved with a GET statement you can deblock the data with MOVE or REMAP statements.
MAP (SAM) FILL$ = 512 MAP DYNAMIC (SAM) STRING PRT_ID, SINGLE MAFLD, LONG ADIR_OLDN OPEN "DUA1:" FOR INPUT AS FILE #2%, SEQUENTIAL FIXED, & ACCESS READ, MAP SAM WHEN ERROR USE err_hand WHILE 1% = 1% GET #2% FOR I% = 0% TO 11% REMAP (SAM) STRING FILL(I% * 40%), PRT_ID = 32, MAFLD, ADIR_OLDN PRINT PRT_ID, MAFLD, ADIR_OLDN NEXT I% NEXT END WHEN HANDLER err_hand IF ERR <> 11% THEN EXIT HANDLER END IF END HANDLER CLOSE #2% END
18.3. I/O to Mailboxes
A mailbox is a record I/O device that passes data from one process to another. You can use a valid mailbox name as a file name, and treat that mailbox as a normal record file. You must have TMPMBX or PRMMBX privilege to create mailboxes. Mailboxes are created and deleted by system services. For more information about using system services in VSI BASIC for OpenVMS programs, see Chapter 19, Using BASIC in the Common Language Environment.
EXTERNAL INTEGER FUNCTION SYS$CREMBX SYS$STATUS% = SYS$CREMBX(,CHAN%,,,,,"CONFIRMATION_MBX")
If you supply a logical name for the mailbox, be sure that it is in uppercase letters. Once you create the mailbox, you can use it as a logical file name.
The following two examples, when executed on two separate processes, allow you to send and receive data from one process to another.
DECLARE STRING passenger_name, Confirm_msg OPEN "CONFIRMATION_MBX" AS FILE #1% INPUT "WHAT IS THE PASSENGER NAME"; passenger_name PRINT #1%, passenger_name LINPUT #1%, confirm_msg PRINT confirm_msg END
MAP (res) STRING passenger_name = 32% DECLARE WORD mbx_chan, LONG sys_status EXTERNAL LONG FUNCTION sys$crembx (LONG, WORD, LONG, LONG, & LONG, LONG, STRING) WHEN ERROR USE err_trap sys_status = sys$crembx ( ,mbx_chan,,,,,"CONFIRMATION_MBX") OPEN "CONFIRMATION_MBX" FOR INPUT AS FILE #1% LINPUT #1%, passenger_name OPEN "RESER.LST" FOR INPUT AS FILE #2%, & ORGANIZATION INDEXED, MAP RES, ACCESS READ & PRIMARY passenger_name FIND #2%, KEY #0% EQ passenger_name RECEIVING.MSG$ = "Passenger reservation confirmed" PRINT #1%, RECEIVING.MSG$ END WHEN HANDLER err_trap IF (ERR = 155) THEN RECEIVING.MSG$ = "Reservation does not exist" ELSE EXIT HANDLER END IF END HANDLER CLOSE #2%, #1% END PROGRAM
Example 1 requests a passenger name and sends it to the mailbox.
Example 2 looks up the name in an indexed file. If the passenger name exists, Example 2 writes the confirmation message to the mailbox. If the passenger name does not exist, the error handler writes an alternate message. Example 1 then reads the mailbox and returns the result.
VSI BASIC for OpenVMS treats the mailbox as a sequential file. You write to the file with the PRINT # or PUT statement, and read it with the INPUT #, LINPUT #, or GET statement.
Note
All mailbox operations are synchronous. Control does not pass back from a mailbox operation, such as a PUT, to your program until the other program completes the corresponding operation, such as a GET.
18.4. Network I/O
Read and write files on a remote node as you do files on your own system (remote file access)
Exchange data with a process executing at a remote location (task-to-task communication)
18.4.1. Remote File Access
OPEN "WESTON::DUA1:[HOLT]TEST.DAT;2" FOR INPUT AS FILE #2%
Note
You need NETMBX privileges to access files at a remote node.
OPEN 'WESTON"HOLT PASWRD"::DUA0:[HOLT.TMP]INDEXU.DAT;4' & FOR INPUT AS FILE #1%, INDEXED, PRIMARY TEXT$
Do not use the CONNECT clause when opening a file on a remote node or VSI BASIC for OpenVMS will signal the error “Cannot open file” (ERR=162).
18.4.2. Task-to-Task Communication
VSI BASIC for OpenVMS supports task-to-task communication if your account has NETMBX privileges.
- Establish a command file at the remote site to execute the program you want. The program must be in executable image format. For example, you can create the file MARG.COM at the remote site. MARG.COM contains a line to run an image (in this case, COPYT.EXE).
$
RUN COPYT
The OPEN statements in the programs at both nodes must specify the same file attributes.
- Start task-to-task communication by accessing the command file at the remote site. For example, a program at the local node could contain the following line:
OPEN 'WESTON::"TASK = MARG"' AS FILE #1%, SEQUENTIAL
- The system then assigns the logical name SYS$NET to the program at the local node. At the remote node, the program (COPYT.EXE) must use this logical for all operations. For example:
OPEN 'SYS$NET' FOR INPUT AS FILE #1%, SEQUENTIAL
The two programs can then exchange messages. The programs must have a complementary series of send/receive statements.
!Local Program MAP (SJK) MSG$ = 32% OPEN 'WESTON"DAVIS PSWRD"::"TASK = MARG"' & FOR OUTPUT AS FILE #1%, SEQUENTIAL, MAP SJK LINPUT "WHAT IS THE CUSTOMER NAME"; MSG$ PUT #1% GET #1% PRINT MSG$ CLOSE #1% END
!Remote Node Program . . . 10 MAP (SJK) MSG$ = 32% MAP (FIL) NAME$ = 32%, RESERVATION$ = 64% OPEN 'SYS$NET' FOR INPUT AS FILE #1%, SEQUENTIAL, & MAP SJK OPEN 'RESER.DAT'FOR INPUT AS FILE #2%, & INDEXED FIXED, PRIMARY NAME$, MAP FIL GET #1% MSG$ = "NAME CONFIRMED" WHEN ERROR IN 100 FIND #2%, KEY 0% EQ MSG$ USE IF ERR = 153 THEN MSG$ = "ERROR IN NAME" ELSE EXIT HANDLER END IF END WHEN PUT #1% . . . CLOSE #2%, 1% END
The task-to-task communication ends when the files are closed.
See the VSI OpenVMS DECnet Networking Manual and the VSI OpenVMS System Manager's Manual for more information.
18.4.3. Accessing a VAX Rdb/VMS Database
If you have purchased a VAX Rdb/VMS development license, you can store and access data in a VAX Rdb/VMS database from a VSI BASIC for OpenVMS program. To do this, you embed RDO statements in your VSI BASIC for OpenVMS program. Each line of an RDO statement must be preceded by the Rdb/VMS statement flag (&RDB&). VSI BASIC for OpenVMS line numbers cannot be included in any RDO statement line. You then precompile your program with the Rdb/VMS precompiler. The precompiler translates the RDO statements into BASIC statements that make direct calls to Rdb/VMS.
Chapter 19. Using BASIC in the Common Language Environment
External routines written in other OpenVMS languages
OpenVMS Run-Time Library routines
OpenVMS system services
The terms routine, procedure, and function are used throughout this chapter. A routine is a closed, ordered set of instructions that performs one or more specific tasks. Every routine has an entry point (the routine name), and may or may not have an argument list. Procedures and functions are specific types of routines: a procedure is a routine that does not return a value, while a function is a routine that returns a value by assigning that value to the function's identifier.
System routines are prewritten OpenVMS routines that perform common tasks such as finding the square root of a number or allocating virtual memory. You can call any system routine from VSI BASIC for OpenVMS provided that the data structures necessary for that routine are supported. The system routines used most often are OpenVMS Run-Time Library routines and system services. System routines, which are discussed later in this chapter, are documented in detail in the OpenVMS Run-Time Library Routines Volume and the VSI OpenVMS System Services Reference Manual.
19.1. Specifying Parameter-Passing Mechanisms
By reference—BY REF
By descriptor—BY DESC
By value—BY VALUE
The following sections outline each of these parameter-passing mechanisms in more detail.
19.1.1. Passing Parameters by Reference
When you pass a parameter by reference, VSI BASIC for OpenVMS passes the address at which the actual parameter value is stored. In other words, your routine has access to the parameter's storage address; therefore, you can manipulate and change the value of this parameter. Any changes that you make to the value of the parameter in your routine are reflected in the calling routine as well.
19.1.2. Passing Parameters by Descriptor
Character strings
Arrays
Compound data structures
Like parameters passed by reference, any change made to the value of a parameter passed by descriptor is reflected in the calling routine.
19.1.3. Passing Parameters by Value
When you pass a parameter by value, you pass a copy of the parameter value to the routine instead of passing its address. Because the actual value of the parameter is passed, the routine does not have access to the storage location of the parameter; therefore, any changes that you make to the parameter value in the routine do not affect the value of that parameter in the calling routine.
VSI BASIC allows actual and formal parameters to be passed by value.
19.1.4. VSI BASIC for OpenVMS Default Parameter-Passing Mechanisms
Parameter |
BY VALUE |
BY REF |
BY DESC |
---|---|---|---|
Integer and Real Data | |||
Variables |
Yes |
Yes? |
Yes |
Constants |
Yes |
Local copy? |
Local copy |
Expressions |
Yes |
Local copy? |
Local copy |
Elements of a nonvirtual array |
Yes |
Yes? |
Yes |
Virtual array elements |
Yes |
Local copy? |
Local copy |
Nonvirtual entire array |
No |
Yes |
Yes? |
Virtual entire array |
No |
No |
No |
Packed Decimal Data | |||
Variables |
No |
Yes? |
Yes |
Constants |
No |
Local copy? |
Local copy |
Expressions |
No |
Local copy? |
Local copy |
Nonvirtual array elements |
No |
Yes? |
Yes |
Virtual array elements |
No |
Local copy? |
Local copy |
Nonvirtual entire arrays |
No |
Yes |
Yes? |
Virtual entire arrays |
No |
No |
No |
String Data | |||
Variables |
No |
Yes |
Yes? |
Constants |
No |
Local copy |
Local copy? |
Expressions |
No |
Local copy |
Local copy? |
Nonvirtual array elements |
No |
Yes |
Yes? |
Virtual array elements |
No |
Local copy |
Local copy? |
Nonvirtual entire arrays |
No |
Yes |
Yes? |
Virtual entire arrays |
No |
No |
No |
Other Parameters | |||
RECORD variables |
No |
Yes? |
No |
RFA variables |
No |
Yes? |
No |
19.1.5. Creating Local Copies
If a parameter is an expression, function, or virtual array element, then it is not possible to pass the parameter's address. In these cases, VSI BASIC for OpenVMS makes a local copy of the parameter's value and passes this local copy by reference.
DECLARE LONG A CALL SUB1 ((A)) PRINT A END SUB SUB1 (LONG B) B = 3 END SUB
Output
0
DECLARE LONG A CALL SUB1 (A) PRINT A END SUB SUB1 (LONG B) B = 3 END SUB
Output
3
19.1.6. Passing Arrays
In VSI BASIC, if a subprogram or function declares an array in its parameter list, the calling program must pass an array. Passing a null parameter instead would cause the program to fail with a memory access violation.
19.2. Calling External Routines
Most of the steps of calling external routines are the same whether you are calling an external routine written in VSI BASIC for OpenVMS, an external routine written in some other language, a system service, or a OpenVMS Run-Time Library routine. The following sections outline the procedure for calling non-BASIC external routines. For information about calling BASIC routines, see Chapter 12, Program Segmentation.
19.2.1. Determining the Type of Call
Before you call an external routine, you must determine whether the call to the routine should be a function call or a procedure call. You should call a routine as a function if it returns any type of value. If the routine does not return a value, you should call it as a procedure.
19.2.2. Declaring an External Routine and Its Arguments
To call an external routine or system routine you need to declare it as an external procedure or function and to declare the names, data types, and passing mechanisms for the arguments. Arguments can be either required or optional.
The name of the external routine
The data types of all the routine parameters
The passing mechanisms for all the routine parameters, provided that the routine is not written in VSI BASIC for OpenVMS
When you declare an external routine, use the EXTERNAL statement. This allows you to specify the data types and parameter-passing mechanisms only once.
EXTERNAL SUB cobsub (LONG BY REF, STRING BY REF)
EXTERNAL SUB allocate(LONG, ANY,)
A parameter declared as OPTIONAL indicates that all following parameters are optional. You can have both required and optional parameters. The required parameters, however, must appear before the OPTIONAL keyword because all parameters following it are considered optional.
EXTERNAL LONG FUNCTION LIB$LOOKUP_KEY(STRING, LONG, OPTIONAL LONG, STRING, INTEGER)
For more information about using the EXTERNAL statement, see the VSI BASIC Reference Manual.
19.2.3. Calling the Routine
Once you have declared an external routine, you can invoke it. To invoke a procedure, you use the CALL statement. To invoke a function, you use the function name in an expression. You must specify the name of the routine being invoked and all parameters required for that routine. Make sure the data types and passing mechanisms for the actual parameters you are passing match those you declared earlier, and those declared in the routine.
If you do not want to specify a value for a required parameter, you can pass a null argument by inserting a comma as a placeholder in the argument list. If you are passing a parameter using a mechanism other than the default passing mechanism for that data type, you must specify the passing mechanism in the CALL statement or the function invocation.
EXTERNAL SUB allocate(LONG, ANY,) . . . CALL allocate (entity%, a$, 1%)
EXTERNAL LONG FUNCTION LIB$LOOKUP_KEY(STRING, LONG, OPTIONAL LONG, STRING, INTEGER) . . . ret_status% = LIB$LOOKUP_KEY(value$, point%)
Note that if the actual parameter's data type in the CALL statement does not match that specified in the EXTERNAL statement, VSI BASIC for OpenVMS reports the compile-time informational message “Mode for parameter of routine changed to match declaration.” This tells you that VSI BASIC for OpenVMS has made a local copy of the value of the parameter, and that this local copy has the data type specified in the EXTERNAL declaration. VSI BASIC for OpenVMS warns you of this because the change means that the parameter can no longer be modified by the subprogram. If VSI BASIC for OpenVMS cannot convert the data type, VSI BASIC for OpenVMS signals the error “Mode for parameter of routine not as declared.”
The routine being called receives control, executes, and then returns control to the calling routine at the next statement after the CALL statement or function invocation.
EXTERNAL LONG FUNCTION compare (LONG, LONG) EXTERNAL SUB come_back_now (LONG BY VALUE) CALL come_back_now (LOC(compare) BY VALUE)
19.3. Calling VSI BASIC for OpenVMS Subprograms from Other Languages
When you call a VSI BASIC for OpenVMS subprogram from another language, there are some additional considerations that you should be aware of. For example, although VSI BASIC for OpenVMS 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 VSI BASIC.
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 VSI BASIC for OpenVMS programs.
Pre-extend the string. Set the string variable equal to SPACE$ (n), where n is large enough to receive the result.
Define the string as fixed-length. Name the string in a COMMON or MAP statement.
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 VSI BASIC for OpenVMS arrays are zero-based by default. For example, in FORTRAN the array Two_D(5,3) represents a 5 by 3 matrix, while in VSI BASIC for OpenVMS the array Two_d(5,3) represents a 6 by 4 matrix. You can adjust your array bounds in VSI BASIC for OpenVMS by using the keyword TO when defining the array bounds. For more information about array bounds, see Chapter 6, Arrays.
Reverse array bounds in parameter lists
Switch row and column variables within loops in your program module
You can pass only the data types that VSI BASIC for OpenVMS and FORTRAN have in common. You cannot pass a complex number from a FORTRAN program to a VSI BASIC for OpenVMS program, because VSI BASIC for OpenVMS does not support complex numbers. However, you can pass a complex number as two floating-point numbers and treat them independently in the VSI BASIC for OpenVMS 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 sections.
19.4.1. OpenVMS Run-Time Library Routines
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 |
19.4.2. System Service Routines
System services are system routines that perform a variety of tasks such as controlling processes, communicating among processes, and coordinating I/O.
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 |
19.4.3. System Routine Arguments
OpenVMS usage
Data type
Type of access allowed
Passing mechanism
OpenVMS Usage |
BASIC Implementation |
---|---|
access_bit_names |
Not applicable (NA) |
access_mode |
BYTE (signed) |
address |
LONG |
address_range |
LONG address_range? or RECORD address_range LONG beginning_address LONG ending_address END RECORD |
arg_list |
NA |
ast_procedure |
EXTERNAL LONG FUNCTION ast_proc ? |
boolean |
LONG |
byte_signed |
BYTE |
byte_unsigned |
BYTE ? |
channel |
WORD |
char_string |
STRING |
complex_number |
RECORD complex REAL real_part REAL imaginary_part END RECORD |
cond_value |
LONG |
context |
LONG |
date_time |
QUAD |
device_name |
STRING |
ef_cluster_name |
STRING |
ef_number |
LONG |
exit_handler_block |
RECORD EHCB LONG flink LONG handler_addr BYTE arg_count BYTE FILL(3) LONG status_value_addr END RECORD |
fab |
NA |
file_protection |
LONG |
floating_point |
SINGLE DOUBLE GFLOAT SFLOAT TFLOAT XFLOAT |
function_code |
RECORD function-code WORD major-function WORD subfunction END RECORD |
identifier |
LONG |
io_status_block |
RECORD iosb WORD iosb_field(1 to 4) END RECORD |
item_list_2 |
RECORD item_list_two GROUP item(15) VARIANT CASE WORD comp_length WORD code LONG comp_address CASE LONG terminator END VARIANT END GROUP END RECORD |
item_list_3 |
RECORD item_list_3 GROUP item (15) VARIANT CASE WORD buf_len WORD code LONG buffer_address LONG length_address CASE LONG terminator END VARIANT END GROUP END RECORD |
item_list_pair |
RECORD item_list_pair GROUP item(15) VARIANT CASE LONG code LONG item_value CASE LONG terminator END VARIANT END GROUP END RECORD item_list_pair |
item_quota_list |
RECORD item_quota_list GROUP quota(n) VARIANT CASE BYTE quota_name LONG item_value CASE BYTE list_end END VARIANT END GROUP END RECORD |
lock_id |
LONG |
lock_status_block |
NA |
lock_value_block |
NA |
logical_name |
STRING |
longword_signed |
LONG |
longword_unsigned |
LONG? |
mask_byte |
BYTE |
mask_longword |
LONG |
mask_quadword |
QUAD |
mask_word |
WORD |
null_arg |
A null argument is indicated by a comma used as a placekeeper in the argument list. |
octaword_signed |
BASIC$OCTAWORD? |
octaword_unsigned |
BASIC$OCTAWORD? |
page_protection |
LONG |
procedure |
EXTERNAL LONG FUNCTION proc |
process_id |
LONG |
process_name |
STRING |
quadword_signed |
QUAD |
quadword_unsigned |
QUAD? |
rights_holder |
QUAD |
rights_id |
LONG |
rab |
NA |
section_id |
QUAD |
section_name |
STRING |
system_access_id |
QUAD |
time_name |
STRING |
uic |
LONG |
user_arg |
LONG |
varying_arg |
Dependent upon application. |
vector_byte_signed |
BYTE array(n) |
vector_byte_unsigned |
BYTE array(n)? |
vector_longword_signed |
LONG array(n) |
vector_longword_unsigned |
LONG array(n)? |
vector_quadword_signed |
QUAD array(n) |
vector_quadword_unsigned |
QUAD array(n)? |
vector_word_signed |
WORD array(n) |
vector_word_unsigned |
WORD array(n)? |
word_signed |
WORD |
word_unsigned |
WORD? |
- [,optional-argument]
- ,[optional-argument]
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.
Because symbolic definition names are mnemonic, the program is easier to read and understand.
It is easier to write the symbolic definition and let the OpenVMS Linker fill in the value, than to look up the value associated with the symbol and include that value in the program.
Should the value associated with a symbol ever change, you must relink the program. To change a hard-coded definition, you must edit the source file, then recompile and relink.
Symbolic definitions used by system services are located in the default system library, STARLET.OLB.
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.
%INCLUDE "SMGDEF" %FROM %LIBRARY "SYS$LIBRARY:BASIC$STARLET.TLB"
For more information about including text libraries, see Chapter 16, Compiler Directives.
19.4.5. Condition Values
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.
ret_status = SMG$CREATE_PASTEBOARD(pb_id) IF (ret_status <> SS$_NORMAL) THEN CALL LIB$STOP(ret_status BY VALUE) END IF
ret_status = SMG$CREATE_PASTEBOARD(pb_id) IF (ret_status AND 1%) = 0% THEN CALL LIB$STOP(ret_status BY VALUE) END IF
In general, you can check for a particular success or failure code or you can test the condition value returned against all success codes or all failure codes.
19.5. Examples of Calling System Routines
This section provides complete examples of calling system routines from VSI BASIC for OpenVMS. In addition to the examples provided, the VMS Run-Time Library Routines Volume and the VSI OpenVMS System Services Reference Manual also provide examples for selected routines. See these manuals for help about the use of a specific system routine.
Example 19.3, “Calling System Services” uses a function that invokes the SYS$TRNLNM system service. SYS$TRNLNM translates a logical name to an equivalence name. It places the equivalence name string into a string variable you supply in the parameter list.
Define the string variable's length in a MAP, COMMON, or RECORD definition.
Assign a long string to the variable (for example, A$ = SPACE$(80)). This pre-extends the variable so that it is long enough to receive all of the returned data.
Output
Successful $QIOW output! Successful $QIOW output! Successful $QIOW output! Successful $QIOW output!
In addition to invoking the function SYS$QIOW, the previous example also invokes the function SYS$ASSIGN. This function provides a process with an I/O channel so that input and output operations can be performed on a logical device name (my_term). As soon as SYS$ASSIGN is invoked and a path is established to the device, a counter is set up to invoke the $QIOW function four times. Once all I/O operations are complete, $QIOW returns to the caller.
19.6. OpenVMS Calling Standard
The primary purpose of the OpenVMS Calling Standard is to define the concepts for invoking routines and passing data between them. For more information, see the VSI OpenVMS Calling Standard.
19.7. Additional Information
The information provided on system routines in this chapter is general to all system services and OpenVMS Run-Time Library routines. For specific information about these routines, see the VMS Run-Time Library Routines Volume and the VSI OpenVMS System Services Reference Manual.
Chapter 20. Libraries and Shareable Images
Libraries and shareable images allow you to access program symbols and incorporate commonly used routines into your source code. This chapter describes how to create and access libraries and shareable images in VSI BASIC.
20.1. Overview of Libraries
Libraries are files that can contain object modules, text modules, and shareable images. There are two types of libraries: system-supplied and user-supplied. System-supplied libraries are provided by the OpenVMS system, and user-supplied libraries are libraries that you create.
Shareable images are similar to libraries; they contain code that can be shared by other programs. However, shareable images contain executable code rather than object code.
If you have routines that are used in many programs, placing the routines in object module libraries or shareable image libraries lets you access them at link time. You do not need to include the routines in the source code, thus shortening compilation time and conserving disk space.
If you have routines that are used simultaneously by many different programs, placing the routines in installed shareable images can improve performance at run time, conserve main physical memory, and reduce paging I/O because one copy of the executable code is shared by all users.
When you link programs, object module libraries, shareable image libraries, and shareable images can contain object code created by any native mode compiler or assembler.
For more understanding of libraries and shareable images, see the VSI OpenVMS Linker Utility Manual and the Guide to Creating OpenVMS Modular Procedures. For more information about installing shareable images, see the VSI OpenVMS System Manager's Manual. For information about text libraries, see Chapter 16, Compiler Directives.
20.2. System-Supplied Libraries
System Library |
Description |
---|---|
IMAGELIB.OLB |
Contains symbol tables for all Run-Time Library (RTL) shareable images that are part of the OpenVMS operating system—for example, an OpenVMS RTL routine is called Lib$FAO. |
STARLET.OLB |
An object module library containing the object files used to create the shareable image version of the OpenVMS RTL, and other less frequently used procedures. If program symbols remain unresolved after the OpenVMS Linker searches IMAGELIB.OLB, the linker then searches this library. |
Modules and libraries specified in the LINK command line, in the order given
User-supplied libraries (logicals of the form LNK$LIBRARY and LNK$LIBRARY_1 through LNK$LIBRARY_999)
Images contained in IMAGELIB.OLB
Modules contained in STARLET.OLB
The linker only includes references to needed shareable images in the image being created. You can use the /NOSYSSHR qualifier to the LINK command to suppress the linker's search of RTL shareable images. Similarly, you can use the /NOSYSLIB qualifier to suppress the linker's search of both RTL shareable images and STARLET.OLB.
The linker searches user-supplied libraries before searching the default system library. If one of your modules has the same name (program symbol) as an OpenVMS System Service or an RTL routine, the linker includes your module in the resulting image rather than the system service or RTL routine.
20.3. Creating User-Supplied Object Module Libraries
$
BASIC MODULE1,MODULE2
$
LIBRARY/CREATE TESTLIB1.OLB MODULE1.OBJ,MODULE2.OBJ
In the previous example, the BASIC command creates object files from MODULE1.BAS and MODULE2.BAS. The LIBRARY command creates an object module library named TESTLIB1.OLB and inserts MODULE1.OBJ and MODULE2.OBJ into that library. See the VSI OpenVMS DCL Dictionary for more information about the LIBRARY command.
20.3.1. Accessing User-Supplied Object Module Libraries
$
LINK MAIN,TESTLIB/LIBRARY
This command instructs the linker to search the library TESTLIB.OLB for any unresolved symbols in the VSI BASIC for OpenVMS object module MAIN.OBJ.
$
LINK MAIN,TESTLIB/LIBRARY/INCLUDE = (module1,module2)
This command instructs the linker to include module1 and module2 from the library TESTLIB.OLB, whether or not it needs these modules to resolve symbols.
You can access user-supplied object module libraries automatically. However, a program executing at DCL level does not automatically search libraries that are assigned to the logical name BASIC$LIB0. Instead, the linker searches libraries that are assigned to the logical name LNK$LIBRARY. If you have more than one library for the linker to search, you must number these libraries consecutively; otherwise, the linker does not search past the first missing logical name. The linker allows you to number libraries from 1 to 999.
$
DEFINE LNK$LIBRARY USER$$DEV:[KELLY]TESTLIB.OLB
$
DEFINE LNK$LIBRARY_1 USER$$DEV:[KELLY]TESTLIB1.OLB
$
DEFINE LNK$LIBRARY_2 USER$$DEV:[KELLY]TESTLIB2.OLB
After you issue these commands, a program executing at DCL level automatically accesses these three library files to resolve program symbols.
20.4. Shareable Images
Shareable images are not directly executable. They contain executable code that can be shared by other images and are intended to be included by the linker in other images.
Conserving disk storage space
Conserving main physical memory
Reducing paging I/O
Allowing shared memory-resident databases
Eliminating the need to relink programs that access a new version of a shared routine
Note
Some of these benefits can only be realized if the shareable image is installed with the OpenVMS Install utility (Install).
$
LINK/SHAREABLE prog1
This command creates an image that can be linked to other programs. You cannot execute a shareable image with the DCL command RUN.
When a program is linked with a shareable image, the required shareable image code is not included in the created executable image on the disk. This code is included by the image activator at run time. Therefore, many programs can reside on disk and be bound with a particular shareable image, and only one physical copy of that shareable image file needs to exist on disk.
If a shareable image has been installed using the OpenVMS Install utility, you conserve physical memory and potentially reduce paging I/O. Many processes can include the physical memory pages of an installed shareable image in their address space. This reduces the requirements for physical memory.
Paging occurs when a process attempts to access a virtual address that is not in the process working set. When this page fault occurs, the page is either in a disk file, in which case paging I/O is required, or is already in physical memory. If a page fault occurs for a shared page, the shared page may already be resident in memory and no paging I/O is required.
20.4.1. Accessing Shareable Images
Write and compile a program unit that is to be inserted into a shareable image.
Create an options file required for the link operation.
Link the program with the /SHAREABLE qualifier, and specify the options file with the /OPTION qualifier.
Write a main program that accesses the routine in the shareable image.
Compile the main program, and link it with the shareable image.
- Write and compile a program unit that is to be inserted into a shareable image.
!Program name - ADD.BAS FUNCTION REAL ADD (LONG A, LONG B) ADD = A + B FUNCTIONEND
- Create an options file that will export the function for the link operation.
! Program name - ADDSUB.OPT SYMBOL_ADDER = (ADD=PROCEDURE)
- Link the program with the qualifiers /SHAREABLE and /OPTION.
$
LINK/SHAREABLE ADD, ADDSUB/OPTION
Copy the shareable image to SYS$SHARE:, or define a logical name to the full image file specification. For example,$ Define ADD Sys$Login:Add.exe
- Write a main program that accesses the routine in the shareable image.
!Program name - CALLADD.BAS EXTERNAL REAL FUNCTION ADD (LONG, LONG) DECLARE LONG X,Y X = 1 Y = 2 PRINT ADD(X,Y) END
Compile the main program, and link it with the shareable image.
$
LINK CALLADD,ADDMAIN/OPTION
!Options file - ADDMAIN.OPT ADD/SHAREABLE
$
DEFINE MYSHR DISK$WORKDISK:[MYDIR]MYSHR.EXE
This is a simple example of using shareable images. For more information, see the VSI OpenVMS Linker Utility Manual and the Guide to Creating OpenVMS Modular Procedures.
Chapter 21. Using CDD/Repository with BASIC
This chapter explains how you can take advantage of CDD/Repository capabilities. For more detailed information about CDD/Repository, see Using CDD/Repository on VMS Systems.
21.1. Overview of CDD/Repository
CDD/Repository is a common data dictionary tool that supports sharing of data definitions by OpenVMS programming languages and information architecture products. Each language or product translates the generic definitions stored in CDD/Repository language- or product-specific definitions that it can use.
BASIC supports CDD/Repository features including dependency recording. Dependency recording allows you to record (or track) which programs use CDD/Repository data definitions. Dependency recording helps evaluate the effort needed to change a record definition by identifying the modules that need to be modified, recompiled, or both.
To support dependency recording, CDD/Repository uses a dictionary structure known as CDO-format. (The type of dictionary used in CDD versions prior to Version 4.0 is known as DMU-format.) You can have many CDO-format dictionaries on an OpenVMS system (but only one DMU-format dictionary). The two types of dictionaries can coexist on a system, and a program can refer to data definitions in both types.
21.2. CDD/Repository Concepts
This section introduces CDD/Repository concepts.
21.2.1. Dictionary Formats
DMU-format dictionary
CDO-format dictionary
These dictionaries can coexist on a system to form one logical directory structure. CDD/Repository uses a special dictionary, known as the compatibility dictionary, that allows an application to refer to dictionary definitions without concern about which type of dictionary format the definitions are stored in.
Note
The compatibility dictionary is an installation option for CDD/Repository. If there is no compatibility dictionary, an application program can refer to both types of dictionaries. In this case, refer to the CDO-format dictionary with an anchor origin path name and to the DMU-format dictionary with a CDD$TOP path name. Anchor origin path names are described in Section 21.2.2, “Dictionary Path Names”.
Refer to the CDD/Repository documentation for detailed information about the CDO utility and the compatibility dictionary.
21.2.2. Dictionary Path Names
To access dictionary definitions, you must specify a path name in the %INCLUDE %FROM %CDD or %REPORT %DEPENDENCY directive. The path name tells CDD/Repository where to locate a particular data definition in its directory. A CDD/Repository path name consists of a string of names separated by periods and enclosed in quotation marks.
The origin is the top, or root, of a dictionary directory. This directory contains other dictionary directories, subdictionary directories, and objects.
Dictionary anchor path name
An anchor path name begins with an anchor, which is an OpenVMS directory specification, as the dictionary origin. The anchor specifies the OpenVMS directory that contains the CDO dictionary. This is known as the CDO naming convention. In the following example, MYNODE::DISK$2:[MYDIRECTORY] is the anchor:MYNODE::DISK$2:[MYDIRECTORY]PERSONNEL.EMPLOYEES_REC
CDD$TOP path name
Use this to refer to either DMU-format dictionary definitions or CDO-format dictionary definitions in a compatibility dictionary. The path origin is always CDD$TOP. This is known as the DMU naming convention. For example:CDD$TOP.PERSONNEL.EMPLOYEES_REC
Relative path name
CDD/Repository always begins its search at CDD$TOP (or at the anchor you specify) unless you define another directory or object to be the start of your directory. You can do this by assigning the name of a dictionary directory to the logical name CDD$DEFAULT. For example:$
DEFINE CDD$DEFAULT CDD$TOP.BASIC
Using this command defines the dictionary directory CDD$TOP.BASIC as the default start of your directory. You can override the defined default by specifying CDD$TOP in a path name.
You can omit the origin of a path name and specify a relative path name. Any path name that does not begin with either CDD$TOP or an anchor is automatically appended to the current CDD$DEFAULT. For example, you can specify:PERSONNEL.EMPLOYEES_REC
If CDD$DEFAULT is MYNODE::MY$DISK:[MYDIR], the relative path name is the same as:MYNODE::MY$DISK:[MYDIR]PERSONNEL.EMPLOYEES_REC.
Similarly, if CDD$DEFAULT is CDD$TOP.MYDIR, the relative path name is the same as:CDD$TOP.MYDIR.PERSONNEL.EMPLOYEES_REC.
21.2.3. Dictionary Entities
Several types of entities can exist in a dictionary. For example, DMU-format and CDO-format dictionaries each contain record entities, database entities, and form entities.
VSI BASIC for OpenVMS creates a compiled module entity (and relationships in CDD/Repository dictionaries that depend on compiled module entities) only if the compilation generates an object file. Therefore, compiled module entities are not generated if you specify the /NOOBJECT qualifier on the command line or if the program has compilation errors.
21.2.4. Dictionary Relationships
Relationships occur in a CDO-format dictionary when two or more CDO entity definitions are connected in any of several possible ways. For example, you can relate a set of field definitions to a record definition by including the field names in the record definition.
See the CDD/Repository documentation for detailed information about relationships in a CDO-format dictionary.
21.2.5. Extracting CDD/Repository Data Definitions
A data definition is one type of a CDD/Repository object. In VSI BASIC for OpenVMS, you can extract only data definition objects into your program.
%INCLUDE %FROM %CDD "CDD$TOP.BASIC.BASICDEF"
The %INCLUDE %FROM %CDD directive extracts the CDD/Repository data definition you specify and translates it into VSI BASIC for OpenVMS syntax. In VSI BASIC for OpenVMS, the syntax for data definitions or data structures is defined by the RECORD statement.
After a CDD/Repository data definition is translated into RECORD statement syntax, you can reference the name of the RECORD statement in your VSI BASIC for OpenVMS programs. After compilation, the translated RECORD statement is included as a part of your program's listing.
The following is an example of a CDD/Repository data definition and the translated VSI BASIC for OpenVMS RECORD statement. The examples in this chapter are CDD/Repository data definitions in DMU-format that were written in the Common Data Definition Language (CDDL). In all examples, a CDDL data definition is displayed in lowercase letters, and the translated RECORD statement is displayed in uppercase letters.
CDDL Definition
define record CDD$top.basic.basicdef description is /* This is an example record containing only data types supported by VSI BASIC */. employee structure. street datatype is text size is 30 characters. city datatype is text size is 30 characters. state datatype is text size is 2 characters. zip_code structure. new datatype is packed decimal size is 4 digits. old datatype is packed decimal size is 5 digits. end zip_code structure. emp_number datatype is signed word. wage_class datatype is text size is 2 characters. salary_ytd datatype is d_floating. end employee structure. end basicdef.
Translated RECORD Statement
C1 ! This is an example record containing C1 ! only data types supported by VSI BASIC C1 RECORD EMPLOYEE ! UNSPECIFIED C1 STRING STREET = 30 ! TEXT C1 STRING CITY = 30 ! TEXT C1 STRING STATE = 2 ! TEXT C1 GROUP ZIP_CODE ! UNSPECIFIED C1 DECIMAL(4 ,0 ) NEW ! PACKED DECIMAL C1 DECIMAL(5 ,0 ) OLD ! PACKED DECIMAL C1 END GROUP C1 WORD EMP_NUMBER ! SIGNED WORD C1 STRING WAGE_CLASS = 2 ! TEXT C1 DOUBLE SALARY_YTD ! D_FLOATING C1 END RECORD
For DMU-format definitions, BASIC takes the field name specified in the first CDDL STRUCTURE statement and assigns that name to VSI BASIC for OpenVMS RECORD. For CDO-format definitions, BASIC takes the record name from the CDO DEFINE RECORD statement and assigns that name to a VSI BASIC for OpenVMS RECORD. In the previous example, the first CDD/Repository structure statement is employee structure. When VSI BASIC for OpenVMS translates this line of a CDD/Repository data definition, it names the record EMPLOYEE. If this first structure is unnamed, VSI BASIC for OpenVMS signals the error “Record from CDD/Repository does not have a record name.”
Translates the field name in any subsequent CDD/Repository STRUCTURE statement to be the name of a group. In the previous example, the second STRUCTURE statement, zip_code structure, is translated to GROUP ZIP_CODE.
Translates subordinate field names in CDD/Repository STRUCTURE statements to elementary components in the RECORD statement. In the previous example, the subordinate field name street is translated to STRING STREET.
Begins each line of the RECORD statement with the letter “C” followed by a number. The letter “C” tells you that the RECORD statement is translated from a CDD/Repository data definition. The number tells you the nesting level of the %INCLUDE %FROM %CDD directive within the source program. For example, if your source program directly extracts a CDD/Repository record definition, then each line is preceded by “C1.” If the CDD/Repository extraction came from a file included in the source program, then each line of the record definition is preceded by “C2,” and so on.
Includes the explanatory text in the CDDL DESCRIPTION clause as comment fields.
Translates the data type text in the subordinate field to a comment field that tells you the data type of each elementary RECORD component. For example, the comment ! TEXT tells you that STRING STREET is a text data type.
VSI BASIC for OpenVMS requires that a CDD/Repository data definition include a minimum of one structure to be translated into a RECORD statement. If a CDD/Repository data definition contains only a single subordinate field (without a structure), VSI BASIC for OpenVMS signals an error because it cannot give a name to the RECORD statement. You cannot include a CDO FIELD definition in a VSI BASIC for OpenVMS program. You can, however, include CDO RECORD definitions that contain that field.
For more information about how VSI BASIC for OpenVMS translates CDD/Repository data types, see Section 21.9, “ CDD/Repository Data Types”.
21.3. Using CDD/Repository with BASIC
When dependency recording is in effect, the compiler updates the CDO-format dictionary to show what dictionary data entities are used by the program (the data dependencies created by the compilation).
Use either or both of the VSI BASIC for OpenVMS lexical directives, %INCLUDE %FROM %CDD and %REPORT %DEPENDENCY, in the source program to define the dependency relationships you want to create between your program and definitions in the CDO-format dictionary.
Establish a CDO-format dictionary called CDD$DEFAULT.
Include the /DEPENDENCY_DATA qualifier in the BASIC command that compiles the module.
21.3.1. /DEPENDENCY_DATA Qualifier
When you compile a program that references CDO-format data definitions, you can include the qualifier in the BASIC command line. The /DEPENDENCY_DATA qualifier instructs the compiler to create dependency relationships (as defined in the program by %INCLUDE and %REPORT directives) and update the dictionary to show those relationships.
To prevent update of the dictionary, specify the default, /NODEPENDENCY_DATA. The compiler can extract record definitions from the dictionary (as specified by %INCLUDE %FROM %CDD directives in the program) but not update the dictionary. The compilation does not add compiled module entities and file entities to the dictionary, nor does it create dependency relationships in the dictionary, unless you specify the /DEPENDENCY_DATA qualifier.
21.3.2. Creating Relationships with Included Record Definitions
In Section 21.2.4, “Dictionary Relationships” a record description is defined as a set of fields (thus establishing a simple relationship in CDD/Repository between the record and its fields). With that record description defined, you can include it in a VSI BASIC for OpenVMS program.
%INCLUDE %FROM %CDD "pathname"
PROGRAM EXAMPLE1 %INCLUDE %FROM %CDD "CDD$TOP.SMITH.ADDRESS_REC" DECLARE ADDRESS_REC TEST_RECORD INPUT "First name";TEST_RECORD::FIRST_NAME INPUT "Last name";TEST_RECORD::LAST_NAME INPUT "Address";TEST_RECORD::ADDRESS INPUT "City";TEST_RECORD::CITY INPUT "State";TEST_RECORD::STATE INPUT "Zip code";TEST_RECORD::ZIP_CODE PRINT TEST_RECORD::FIRST_NAME; TEST_RECORD::LAST_NAME PRINT TEST_RECORD::ADDRESS PRINT TEST_RECORD::CITY; TEST_RECORD::STATE; TEST_RECORD::ZIP_CODE
1 PROGRAM EXAMPLE1 2 %INCLUDE %FROM %CDD "CDD$TOP.SMITH.ADDRESS_REC" C1 RECORD ADDRESS_REC ! UNSPECIFIED C1 STRING FIRST_NAME = 20 ! TEXT C1 STRING LAST_NAME = 30 ! TEXT C1 STRING ADDRESS = 40 ! TEXT C1 STRING CITY = 20 ! TEXT C1 STRING STATE = 2 ! TEXT C1 DECIMAL(5 ,0 ) ZIP_CODE ! PACKED DECIMAL C1 END RECORD 3 DECLARE ADDRESS_REC TEST_RECORD 4 INPUT "First name";TEST_RECORD::FIRST_NAME 5 INPUT "Last name";TEST_RECORD::LAST_NAME 6 INPUT "Address";TEST_RECORD::ADDRESS 7 INPUT "City";TEST_RECORD::CITY 8 INPUT "State";TEST_RECORD::STATE 9 INPUT "Zip code";TEST_RECORD::ZIP_CODE 10 11 PRINT TEST_RECORD::FIRST_NAME; TEST_RECORD::LAST_NAME 12 PRINT TEST_RECORD::ADDRESS 13 PRINT TEST_RECORD::CITY; TEST_RECORD::STATE; TEST_RECORD::ZIP_CODE
With a CDO-format dictionary, you can also instruct the dictionary to create and maintain a formal relationship between the record description and the compiled module entity that represents your program in the dictionary.
$ BASIC/DEPENDENCY_DATA EX1.BAS
CDO> DIRECTORY Directory SYS$COMMON:[CDDPLUS]SMITH ADDRESS;1 FIELD ADDRESS_REC;1 RECORD CITY;1 FIELD EXAMPLE1;1 CDD$COMPILED_MODULE FIRST_NAME;1 FIELD LAST_NAME;1 FIELD STATE;1 FIELD ZIP_CODE;1 FIELD . . .
CDO> SHOW USES ADDRESS_REC Owners of SYS$COMMON:[CDDPLUS]SMITH.ADDRESS_REC;1 | SYS$COMMON:[CDDPLUS]SMITH.EXAMPLE1;1 (Type : CDD$COMPILED_MODULE) | | via CDD$COMPILED_DEPENDS_ON
CDO> SHOW USED_BY EXAMPLE1 Members of SYS$COMMON:[CDDPLUS]SMITH.EXAMPLE1;1 | EX1 (Type : CDD$FILE) | | via CDD$IN_FILE | SYS$COMMON:[CDDPLUS]SMITH.ADDRESS_REC;1 (Type : RECORD) | | via CDD$COMPILED_DEPENDS_ON
21.4. Creating Relationships for Referenced Dictionary Entities
The compiler can create a relationship between a compiled module entity and any dictionary entity that a program references (such as a VAX Rdb/VMS database or a form definition). The referenced dictionary entity is not copied to the program. Instead, the compiled program references the dictionary entity at run time or with the help of a preprocessor.
%REPORT %DEPENDENCY "pathname" ["relationship-type"]
The "pathname" parameter identifies the dictionary item that the compiled object module references. The path name can specify a CDO-format dictionary item (with an anchor as the first element), or it can specify a CDO-format item in the compatibility dictionary (which can be specified either as a CDD$TOP path name or as an anchor path name). See Section 21.2.2, “Dictionary Path Names” for a full description of the path name options.
CDD$COMPILED_DEPENDS_ON
This specifies a relationship that links a compiled object module to the element that goes into the compilation. This is the default.
The /DEPENDENCY_DATA qualifier is specified in the BASIC command line. (If it is not specified, the compiler checks syntax but does not update the dictionary to reflect this usage of the item.)
The current CDD$DEFAULT dictionary points to a directory in a CDO dictionary.
The dictionary item specified by pathname is in a CDO-format dictionary. (No relationship can be created in a DMU-format dictionary).
%REPORT %DEPENDENCY "DISK1$:[CDDPLUS.BASIC]SMITH.DOG_DATABASE"
$ BASIC/DEPENDENCY_DATA DOG_REPORT
CDO> DIR Directory DISK1$:[CDDPLUS.BASIC]SMITH BREED;1 FIELD CALL_NAME;1 FIELD DOG_REPORT$MAIN;1 CDD$COMPILED_MODULE DOG_DATABASE;1 CDD$DATABASE DOG_INFORMATION;1 CDD$RMS_DATABASE DOG_REC;1 RECORD OWNER_NUMBER;1 FIELD REG_DOG_NAME;1 FIELD CDO> SHOW USES DOG_DATABASE Owners of DISK1$:[CDDPLUS.BASIC]SMITH.DOG_DATABASE;1 | DISK1$:[CDDPLUS.BASIC]SMITH.DOG_REPORT$MAIN;1 | (Type : CDD$COMPILED_MODULE) | | via CDD$COMPILED_DEPENDS_ON CDO> SHOW USED_BY DOG_REPORT$MAIN Members of DISK1$:[CDDPLUS.BASIC]SMITH.DOG_REPORT$MAIN;1 | DOG_REPORT (Type : CDD$FILE) | | via CDD$IN_FILE | DISK1$:[CDDPLUS.BASIC]SMITH.DOG_DATABASE;1 (Type : CDD$DATABASE) | | via CDD$COMPILED_DEPENDS_ON
21.5. Specifying a CDD History List Entry
When your VSI BASIC for OpenVMS program accesses CDD/Repository, you have the option of entering a history list entry in the database. The history list entry provides a history of users that access CDD/Repository.
$ BASIC/DEPENDENCY_DATA/AUDIT="History text goes here" EX1.BAS
Note that instead of typing the text directly on the command line, you can also specify a file specification that contains the history entry.
When you specify /AUDIT, a history list entry is created for each compiled module entity that the compilation creates. In addition, the compilation will add a history list entry to each data definition that your program extracts with the %INCLUDE %FROM %CDD directive.
CDO> SHOW GENERIC CDD$COMPILED_MODULE EXAMPLE1 /AUDIT Definition of EXAMPLE1 (Type : CDD$COMPILED_MODULE) | History entered by SMITH ([SMITH]) | using BASIC Vn.n | to CREATE definition on 25-APR-1989 13:04:01.48 | Explanation: | "History text goes here"
21.6. CDD/Repository Arrays
Multidimensional arrays (the ARRAY clause)
One-dimensional, fixed length arrays (the OCCURS clause or ARRAY clause)
One-dimensional, variable length arrays (the OCCURS DEPENDING ON clause—note that VSI BASIC for OpenVMS does not support this clause)
Arrays are valid for any CDD/Repository field. VSI BASIC for OpenVMS does not support dimensions on a RECORD statement; therefore, you cannot declare an entire RECORD statement as an array. However, you can dimension an instance of the record.
The following is an example of a CDDL data definition containing arrays and the corresponding VSI BASIC for OpenVMS RECORD statement:
CDDL Definition
define record CDD$top.basic.array1 description is /* test arrays */. array_1 structure. my_byte array 0:2 datatype signed byte. my_string array 0:10 datatype text size 10. my_s_real array 0:2 0:4 datatype f_floating. my_d_real array 1:3 datatype d_floating. my_g_real occurs 4 times datatype g_floating. my_h_real occurs 4 times datatype h_floating. end array_1 structure. end array1.
Translated RECORD Statement
1 %INCLUDE %FROM %CDD "CDD$TOP.BASIC.ARRAY1" C1 ! test arrays C1 RECORD ARRAY_1 ! UNSPECIFIED C1 BYTE MY_BYTE(0 TO 2) ! SIGNED BYTE C1 STRING MY_STRING(0 TO 10) = 10 ! TEXT C1 SINGLE MY_S_REAL(0 TO 2,0 TO 4) ! F_FLOATING C1 DOUBLE MY_D_REAL(1 TO 3) ! D_FLOATING C1 GFLOAT MY_G_REAL(1 TO 4) ! G_FLOATING C1 HFLOAT MY_H_REAL(1 TO 4) ! H_FLOATING C1 END RECORD
By default, arrays in CDD/Repository are row-major. This means that when storage is allocated for the array, the rightmost subscript varies fastest. All VSI BASIC for OpenVMS arrays are row-major. VSI BASIC for OpenVMS does not support column-major arrays. If a CDD/Repository definition containing a column-major array is extracted, VSI BASIC for OpenVMS signals the error “<array-name> from CDD/Repository is a column major array.”
By default, VSI BASIC for OpenVMS extracts an array field from CDD/Repository with the bounds specified in the data definition. However, if you use the qualifier /OLD_VERSION[=CDD_ARRAYS] when you extract a data definition, VSI BASIC for OpenVMS translates the data definition with lower bounds as zero and adjusts the upper bounds. This means that an array with dimensions of (2,5) in CDD/Repository is translated by VSI BASIC for OpenVMS to be an array with a lower bound of 0 and an upper bound of 3. VSI BASIC for OpenVMS issues an informational message to confirm the array bounds when you use this qualifier.
The following CDD/Repository data definition and corresponding RECORD statement are extracted with the /OLD_VERSION[=CDD_ARRAYS] qualifier:
CDDL Definition
define record CDD$top.basic.array2 description is /* test arrays with /old_version[=CDD_ARRAYS] qualifier */. array_2 structure. my_byte array 0:2 datatype signed byte. my_string array 0:10 datatype text size 10. my_s_real array 0:2 0:4 datatype f_floating. my_d_real array 1:3 datatype d_floating. my_g_real occurs 4 times datatype g_floating. dep_item datatype signed longword. my_h_real occurs 4 times datatype h_floating. end array_2 structure. end array2.
Translated RECORD Statement
1 %INCLUDE %FROM %CDD "CDD$TOP.BASIC.ARRAY2" C1 ! test arrays with /old_version[=CDD_ARRAYS] qualifier C1 RECORD ARRAY_2 ! UNSPECIFIED C1 BYTE MY_BYTE(0 TO 2) ! SIGNED BYTE C1 STRING MY_STRING(0 TO 10) = 10 ! TEXT C1 SINGLE MY_S_REAL(0 TO 2,0 TO 4) ! F_FLOATING C1 DOUBLE MY_D_REAL(0 TO 2) ! D_FLOATING C1 GFLOAT MY_G_REAL(0 TO 3) ! G_FLOATING C1 LONG DEP_ITEM ! SIGNED LONGWORD C1 HFLOAT MY_H_REAL(0 TO 3) ! H_FLOATING C1 END RECORD
21.7. CDD/Repository Variants
A variant comprises two or more fields of a record that provide alternative descriptions for the same portion of a record.
The following is an example of a CDDL data definition containing variant fields and the corresponding VSI BASIC for OpenVMS RECORD statement:
CDDL Definition
define record CDD$top.basic.variant_example description is /* test simple variant */. variant_example structure. my_string datatype text size 9. variants. variant. my_s_real datatype f_floating. my_d_real datatype d_floating. end variant. variant. my_g_real datatype g_floating. my_h_real datatype h_floating. end variant. end variants. my_byte datatype signed byte. end variant_example structure. end variant_example.
Translated RECORD Statement
1 %INCLUDE %FROM %CDD "CDD$TOP.BASIC.VARIANT_EXAMPLE" C1 ! test simple variant C1 RECORD VARIANT_EXAMPLE ! UNSPECIFIED C1 STRING MY_STRING = 9 ! TEXT C1 VARIANT C1 CASE C1 SINGLE MY_S_REAL ! F_FLOATING C1 DOUBLE MY_D_REAL ! D_FLOATING C1 CASE C1 GFLOAT MY_G_REAL ! G_FLOATING C1 HFLOAT MY_H_REAL ! H_FLOATING C1 END VARIANT C1 BYTE MY_BYTE ! SIGNED BYTE C1 END RECORD
CDD/Repository data definitions sometimes contain VARIANTS OF field description statements as well
as simple variants. A CDDL or CDO VARIANTS OF statement names a tag variable whose value
at run time determines which of the variant fields is the current variant. VSI BASIC for OpenVMS does not
support the VARIANTS OF statement. If a CDD/Repository data definition containing a VARIANTS
OF statement is extracted, VSI BASIC for OpenVMS signals the informational message,
“<number>
tag value from CDD/Repository ignored”
and treats the VARIANTS OF as an ordinary variant and ignores the tag value.
21.8. NAME FOR BASIC Clause
VSI BASIC for OpenVMS supports the CDDL and CDO field attribute clause NAME FOR BASIC.
name for basic is "subject_name$"
When you assign a name using the NAME FOR BASIC clause in a CDDL or CDO data definition, VSI BASIC for OpenVMS recognizes only this name when you refer to the field. Note that when you use the NAME FOR BASIC clause, you can place dollar sign ($) and percent sign (%) suffixes in your RECORD statement field names.
The following example is a CDDL data definition containing the NAME FOR BASIC clause and the corresponding VSI BASIC for OpenVMS RECORD statement.
CDDL Definition
define record city_study description is /* This example formats data resulting from a study on the relationship between place of birth and earning potential */. info structure. subject_name datatype text size 10 name for basic is "subject_name$". birth_city datatype text size 10 name for basic is "city_of_birth$". salary datatype signed byte name for basic is "salary%". end info structure. end city_study.
Translated RECORD Statement
1 %INCLUDE %FROM %CDD "CDD$TOP.BASIC.CITY_STUDY" C1 ! This example formats data resulting from a C1 ! study on the relationship between place of birth C1 ! and earning potential C1 RECORD INFO ! UNSPECIFIED C1 STRING SUBJECT_NAME$ = 10 ! TEXT C1 STRING CITY_OF_BIRTH$ = 10 ! TEXT C1 BYTE SALARY% ! SIGNED BYTE C1 END RECORD
Caution
The NAME FOR BASIC clause enables you to assign completely different names to the same field.
For more information about the CDDL NAME FOR BASIC field attribute clause, see the CDD/Repository documentation.
21.9. CDD/Repository Data Types
Data Type |
VSI BASIC for OpenVMS Translation |
---|---|
TEXT |
STRING |
SIGNED BYTE |
BYTE |
SIGNED WORD |
WORD |
SIGNED LONGWORD |
LONG |
F_FLOATING |
SINGLE |
D_FLOATING |
DOUBLE |
G_FLOATING |
GFLOAT |
PACKED DECIMAL |
DECIMAL |
If a CDD/Repository data definition containing an unsupported data type is extracted, VSI BASIC for OpenVMS signals
the informational message “Datatype in CDD/Repository not supported, substituted group
for: <field-name>
” and translates the data type by
creating a group to contain the data type field. The group name is the name of the
unsupported data type followed by the text “_VALUE”. This allows you to
access the field name within the group.
An example of how VSI BASIC for OpenVMS translates unsupported CDD/Repository data types is shown in the following CDDL data definition and corresponding VSI BASIC for OpenVMS RECORD statement:
CDDL Definition
define record CDD$top.basic.stock description is /* this is an example data definition that contains data types not supported by VSI BASIC */. stock structure. product_no datatype is text size is 8 characters. date_ordered datatype is date. status_code datatype is unsigned byte. quantity datatype is unsigned longword aligned on longword. location array 1:4 datatype is text size is 30 characters. unit_price datatype is longword. end stock structure. end stock.
Translated RECORD Statement
1 %INCLUDE %FROM %CDD "CDD$TOP.BASIC.STOCK" C1 ! This is an example data definition that contains C1 ! data types not supported by VSI BASIC C1 RECORD STOCK ! UNSPECIFIED C1 STRING PRODUCT_NO = 8 ! TEXT C1 GROUP DATE_ORDERED ! DATE C1 STRING STRING_VALUE = 8 C1 END GROUP C1 GROUP STATUS_CODE ! UNSIGNED BYTE C1 BYTE BYTE_VALUE C1 END GROUP C1 STRING FILL = 3 C1 GROUP QUANTITY ! UNSIGNED LONGWORD C1 LONG LONG_VALUE C1 END GROUP C1 STRING LOCATION(1 TO 4) = 30 ! TEXT C1 GROUP UNIT_PRICE ! UNSIGNED LONGWORD C1 LONG LONG_VALUE C1 END GROUP C1 END RECORD %BASIC-I-CDDSUBGRO, data type in CDD/Repository not supported, substituted group for: STOCK::DATE_ORDERED. %BASIC-I-CDDSUBGRO, data type in CDD/Repository not supported, substituted group for: STOCK::STATUS_CODE. %BASIC-I-CDDSUBGRO, data type in CDD/Repository not supported, substituted group for: STOCK::QUANTITY. %BASIC-I-CDDSUBGRO, data type in CDD/Repository not supported, substituted group for: STOCK::UNIT_PRICE.
Data Type |
VSI BASIC for OpenVMS Translation |
---|---|
UNSIGNED BYTE |
GROUP CDD/Repository-field-name BYTE BYTE_VALUE END GROUP |
UNSIGNED WORD |
GROUP CDD/Repository-field-name WORD WORD_VALUE END GROUP |
UNSIGNED LONGWORD |
GROUP CDD/Repository-field-name LONG LONG_VALUE END GROUP |
SIGNED QUADWORD |
GROUP CDD/Repository-field-name STRING STRING_VALUE = 8 END GROUP |
UNSIGNED QUADWORD |
GROUP CDD/Repository-field-name STRING STRING_VALUE = 8 END GROUP |
SIGNED OCTAWORD |
GROUP CDD/Repository-field-name STRING STRING_VALUE = 16 END GROUP |
UNSIGNED OCTAWORD |
GROUP CDD/Repository-field-name STRING STRING_VALUE = 16 END GROUP |
H_FLOATING |
GROUP CDD/Repository-field-name STRING STRING_VALUE = 16 END GROUP |
F_FLOATING COMPLEX |
GROUP CDD/Repository-field-name SINGLE SINGLE_R_VALUE SINGLE SINGLE_I_VALUE END GROUP |
D_FLOATING COMPLEX |
GROUP CDD/Repository-field-name DOUBLE DOUBLE_R_VALUE DOUBLE DOUBLE_I_VALUE END GROUP |
G_FLOATING COMPLEX |
GROUP CDD/Repository-field-name GFLOAT GFLOAT_R_VALUE GFLOAT GFLOAT_I_VALUE END GROUP |
H_FLOATING COMPLEX |
GROUP CDD/Repository-field-name HFLOAT HFLOAT_R_VALUE HFLOAT HFLOAT_I_VALUE END GROUP |
ZONED NUMERIC |
GROUP CDD/Repository-field-name STRING STRING_VALUE = length END GROUP |
UNSIGNED NUMERIC |
GROUP CDD/Repository-field-name STRING STRING_VALUE = length END GROUP |
LEFT SEPARATE NUMERIC |
GROUP CDD/Repository-field-name STRING STRING_VALUE = length + 1 END GROUP |
LEFT OVERPUNCHED NUMERIC |
GROUP CDD/Repository-field-name STRING STRING_VALUE = length END GROUP |
RIGHT SEPARATE NUMERIC |
GROUP CDD/Repository-field-name STRING STRING_VALUE = length + 1 END GROUP |
RIGHT OVERPUNCHED NUMERIC |
GROUP CDD/Repository-field-name STRING STRING_VALUE = length END GROUP |
VARYING STRING |
GROUP CDD/Repository-field-name WORD WORD_VALUE STRING STRING_VALUE = length END GROUP |
BIT? |
GROUP CDD/Repository-field-name STRING STRING_VALUE = length /8 END GROUP |
DATE |
GROUP CDD/Repository-field-name STRING STRING_VALUE = 8 END GROUP |
POINTER |
GROUP CDD/Repository-field-name LONG LONG_VALUE END GROUP |
UNSPECIFIED |
GROUP CDD/Repository-field-name STRING STRING_VALUE = length END GROUP |
VIRTUAL FIELD |
Ignored |
The following sections describe how VSI BASIC for OpenVMS translates CDD/Repository data types.
21.9.1. Character String Data Types
There are two CDD/Repository character string data types, TEXT and VARYING STRING. The TEXT data type translates directly into the VSI BASIC for OpenVMS STRING data type. VARYING STRING is not a supported VSI BASIC for OpenVMS data type; therefore, VSI BASIC for OpenVMS creates a group to contain the field.
Note
The count field preceding the VARYING STRING is actually an UNSIGNED WORD. Therefore, the count field of a VARYING STRING whose length is greater than 32,767 is interpreted by VSI BASIC for OpenVMS as a negative number.
100 MAP (TEST) BASICSTRINGS MY_REC
The names you use to reference these components in VSI BASIC for OpenVMS are MY_REC::XYZ::WORD_VALUE and MY_REC::XYZ::STRING_VALUE.
21.9.2. Integer Data Types
- SIGNED
- UNSIGNED
- SIZE
- DIGITS
- FRACTION
- BASE
- SCALE
In CDDL, if integer data types are not specified as being signed or unsigned, the default is
unsigned. VSI BASIC for OpenVMS supports only signed BYTE, signed WORD, signed LONGWORD, and signed
QUADWORD integers. If a CDD/Repository data definition containing an unsigned BYTE, WORD,
LONGWORD, or QUADWORD integer is extracted, VSI BASIC for OpenVMS signals the informational message
“Datatype in CDD/Repository not supported, substituted group for:
<field-name>
,” and creates a group to contain the field.
Because the group name is the same as the CDD/Repository field name, VSI BASIC for OpenVMS assigns a new
name to the field. This is shown in the following CDDL data definition and
corresponding VSI BASIC for OpenVMS RECORD statement:
CDDL Definition
define record CDD$top.basic.integers description is /*Test of selected integer data types*/. basicint structure. my_byte datatype is signed byte. my_ubyte datatype is byte. my_word datatype is signed word. my_uword datatype is unsigned word. my_long datatype is signed longword. my_ulong datatype is unsigned longword. end basicint structure. end integers.
Translated RECORD Statement
1 %INCLUDE %FROM %CDD "CDD$TOP.BASIC.INTEGERS" C1 ! Test of selected integer data types C1 RECORD BASICINT ! UNSPECIFIED C1 BYTE MY_BYTE ! SIGNED BYTE C1 GROUP MY_UBYTE ! UNSIGNED BYTE C1 BYTE BYTE_VALUE C1 END GROUP C1 WORD MY_WORD ! SIGNED WORD C1 GROUP MY_UWORD ! UNSIGNED WORD C1 WORD WORD_VALUE C1 END GROUP C1 LONG MY_LONG ! SIGNED LONGWORD C1 GROUP MY_ULONG ! UNSIGNED LONGWORD C1 LONG LONG_VALUE C1 END GROUP C1 END RECORD ................1 %BASIC-I-CDDSUBGRO, 1: data type in CDD/Repository not supported, substituted group for: BASICINT::MY_UBYTE. %BASIC-I-CDDSUBGRO, 1: data type in CDD/Repository not supported, substituted group for: BASICINT::MY_UWORD. %BASIC-I-CDDSUBGRO, 1: data type in CDD/Repository not supported, substituted group for: BASICINT::MY_ULONG.
When the previous data definition is extracted from CDD/Repository, VSI BASIC for OpenVMS signals an informational message for each of the unsigned data types, and names the CDD/Repository unsigned byte field BYTE_VALUE, the CDD/Repository unsigned word field WORD_VALUE, and the CDD/Repository unsigned longword field LONG_VALUE.
VSI BASIC for OpenVMS does not support OCTAWORD integers. If a CDD/Repository definition contains an OCTAWORD
integer, VSI BASIC for OpenVMS signals the informational message “Datatype in CDD/Repository not
supported, substituted group for: <field-name>
”
and creates a group to contain the field and a string component within the group.
The string component is 16 bytes for OCTAWORD integers. For example:
CDDL Definition
define record CDD$top.basic.bigintegers description is /*Test of quadword and octaword integer data types*/. basicint structure. my_quad datatype is signed quadword. my_octa datatype is signed octaword. end basicint structure. end bigintegers.
Translated RECORD Statement
1 %INCLUDE %FROM %CDD "CDD$TOP.BASIC.BIGINTEGERS" C1 ! Test of quadword and octaword integer data types C1 RECORD BASICINT ! UNSPECIFIED C1 QUAD MY_QUAD ! SIGNED QUADWORD C1 GROUP MY_OCTA ! SIGNED OCTAWORD C1 STRING STRING_VALUE = 16 C1 END GROUP C1 END RECORD %BASIC-I-CDDSUBGRO, data type in CDD/Repository not supported, substituted group for: BASICINT::MY_OCTA.
CDD/Repository supports the SCALE keyword to specify an implied exponent in integer data types, and
the BASE keyword (supported in CDDL only) to specify that the scale for a
fixed-point field is to be interpreted in a numeric base other than 10. VSI BASIC for OpenVMS does
not support these integer attributes. Therefore, VSI BASIC for OpenVMS signals the informational
message “ CDD/Repository specifies SCALE for <name>
. Not
supported” for fixed-point fields containing a SCALE specification, and
the error message “ CDD/Repository attributes for <name>
are
other than base 10” for fixed-point fields specifying a base other than
10. For example:
CDDL Definition
define record CDD$top.basic.funnyintegers description is /* Test of quadword and octaword integer data types */. basicint structure. my_byte datatype is signed byte scale 2. my_long datatype is signed longword base 8. end basicint structure. end funnyintegers.
Translated RECORD Statement
1 %INCLUDE %FROM %CDD "CDD$TOP.BASIC.FUNNYINTEGERS" C1 ! Test of quadword and octaword integer data types C1 RECORD BASICINT ! UNSPECIFIED C1 GROUP MY_BYTE ! SIGNED BYTE C1 BYTE BYTE_VALUE C1 END GROUP C1 LONG MY_LONG ! SIGNED LONGWORD C1 END RECORD %BASIC-I-CDDATTSCA, CDD specifies SCALE for BASICINT::MY_BYTE. Not supported %BASIC-E-CDDATTBAS, CDD attributes for BASICINT::MY_LONG are other than base 10
At compilation time, VSI BASIC for OpenVMS also signals these warning errors for each reference to fields that are not base 10 or that have a SCALE.
21.9.3. Floating-Point Data Types
CDD/Repository supports F_floating, D_floating, and G_floating data types.? These correspond to the BASIC SINGLE, DOUBLE, and GFLOAT data types,
respectively. As with fixed-point data types, CDD/Repository also allows the
specification of scale and base for floating-point data types. If a CDD/Repository data
definition contains a floating-point field that specifies a SCALE or BASE, VSI BASIC for OpenVMS
signals the informational message “ CDD/Repository specifies SCALE for
<name>
. Not supported” or the error message
“ CDD/Repository attributes for <name>
are other than
base 10.” For example:
CDDL Definition
define record floats description is /*Test of floating-point data types*/. basicfloat structure. my_single datatype is f_floating scale 3. my_double datatype is d_floating base 16. my_gfloat datatype is g_floating. end basicfloat structure. end floats.
Translated RECORD Statement
1 %INCLUDE %FROM %CDD "CDD$TOP.BASIC.FLOATS" C1 ! Test of floating-point data types C1 RECORD BASICFLOAT ! UNSPECIFIED C1 GROUP MY_SINGLE ! F_FLOATING C1 SINGLE SINGLE_VALUE C1 END GROUP C1 DOUBLE MY_DOUBLE ! D_FLOATING C1 GFLOAT MY_GFLOAT ! G_FLOATING C1 END RECORD ................1 %BASIC-I-CDDATTSCA, 1: CDD specifies SCALE for BASICFLOAT::MY_SINGLE. Not supported %BASIC-E-CDDATTBAS, 1: CDD attributes for BASICFLOAT::MY_DOUBLE are other than base 10
In addition, CDD/Repository supports complex floating-point numbers, but VSI BASIC for OpenVMS does not support them. Complex floating-point numbers consist of a real and an imaginary part. Each part requires the same amount of storage as a simple floating-point number. Therefore, each complex floating-point number requires twice as much storage as a simple floating-point number.
If a CDD/Repository data definition containing complex numbers is extracted, VSI BASIC for OpenVMS
signals the informational message “Datatype in CDD/Repository not supported,
substituted group for <field-name>
,” and creates a
group to contain the field. As before, VSI BASIC for OpenVMS uses the data type and
_VALUE to create the group name, but because each complex
number contains both a real and an imaginary part, VSI BASIC for OpenVMS adds an “_R” to
the name of the real part and an “_I” to the name of the imaginary
part. This is shown in the following CDD/Repository data definition and corresponding
VSI BASIC for OpenVMS RECORD statement:
CDDL Definition
define record CDD$top.basic.complex description is /* test complex data types */. complex structure. my_s_complex_1 datatype f_floating_complex. my_d_complex_1 datatype d_floating_complex. my_g_complex_1 datatype g_floating_complex. end complex structure. end complex.
Translated RECORD Statement
1 %INCLUDE %FROM %CDD "CDD$TOP.BASIC.COMPLEX" C1 ! test complex data types C1 RECORD COMPLEX ! UNSPECIFIED C1 GROUP MY_S_COMPLEX_1 ! F_FLOATING_COMPLEX C1 SINGLE SINGLE_R_VALUE C1 SINGLE SINGLE_I_VALUE C1 END GROUP C1 GROUP MY_D_COMPLEX_1 ! D_FLOATING_COMPLEX C1 DOUBLE DOUBLE_R_VALUE C1 DOUBLE DOUBLE_I_VALUE C1 END GROUP C1 GROUP MY_G_COMPLEX_1 ! G_FLOATING_COMPLEX C1 GFLOAT GFLOAT_R_VALUE C1 GFLOAT GFLOAT_I_VALUE C1 END GROUP C1 END RECORD ................1 %BASIC-I-CDDSUBGRO, 1: data type in CDD/Repository not supported, substituted group for: COMPLEX::MY_S_COMPLEX_1. %BASIC-I-CDDSUBGRO, 1: data type in CDD/Repository not supported, substituted group for: COMPLEX::MY_D_COMPLEX_1. %BASIC-I-CDDSUBGRO, 1: data type in CDD/Repository not supported, substituted group for: COMPLEX::MY_G_COMPLEX_1.
21.9.4. Decimal String Data Types
LEFT OVERPUNCHED NUMERIC
LEFT SEPARATE NUMERIC
RIGHT OVERPUNCHED NUMERIC
RIGHT SEPARATE NUMERIC
PACKED DECIMAL
UNSIGNED NUMERIC
ZONED NUMERIC
VSI BASIC for OpenVMS supports only the PACKED DECIMAL decimal string data type, which corresponds to the VSI BASIC for OpenVMS DECIMAL data type. For all other decimal string data types, VSI BASIC for OpenVMS creates a group with the same name as the CDD/Repository subordinate field, and creates a string record component to contain the field. For example:
CDDL Definition
define record CDD$top.basic.decimalstring description is /* test decimal string data types */. decimalstring structure. my_packed_decimal datatype is packed decimal size is 5 digits 2 fractions. my_zoned_numeric datatype is zoned numeric size is 6 digits 2 fractions. my_unsigned_numeric datatype is unsigned numeric size is 8 digits 4 fractions. my_lef_sep_numeric datatype is left separate numeric size is 10 digits 3 fractions. my_left_ovpnch_numeric datatype is left overpunched numeric size is 5 digits 2 fractions. my_right_sep_numeric datatype is right separate numeric size is 3 digits 1 fractions. my_right_ovpnch_numeric datatype is right overpunched numeric size is 4 digits 2 fractions. end decimalstring structure. end decimalstring.
Translated RECORD Statement
1 %INCLUDE %FROM %CDD "CDD$TOP.BASIC.DECIMALSTRING" C1 ! test decimal string data types C1 RECORD DECIMALSTRING ! UNSPECIFIED C1 DECIMAL(5 ,2 ) MY_PACKED_DECIMAL ! PACKED DECIMAL C1 GROUP MY_ZONED_NUMERIC ! ZONED NUMERIC C1 STRING STRING_VALUE = 6 C1 END GROUP C1 GROUP MY_UNSIGNED_NUMERIC ! UNSIGNED NUMERIC C1 STRING STRING_VALUE = 8 C1 END GROUP C1 GROUP MY_LEF_SEP_NUMERIC ! NUMERIC LEFT ! SEPARATE C1 STRING STRING_VALUE = 11 C1 END GROUP C1 GROUP MY_LEFT_OVPNCH_NUMERIC ! NUMERIC LEFT ! OVERPUNCHED C1 STRING STRING_VALUE = 5 C1 END GROUP C1 GROUP MY_RIGHT_SEP_NUMERIC ! NUMERIC RIGHT ! SEPARATE C1 STRING STRING_VALUE = 4 C1 END GROUP C1 GROUP MY_RIGHT_OVPNCH_NUMERIC ! NUMERIC RIGHT ! OVERPUNCHED C1 STRING STRING_VALUE = 4 C1 END GROUP C1 END RECORD %BASIC-I-CDDSUBGRO, data type in CDD/Repository not supported, substituted group for: DECIMALSTRING::MY_ZONED_NUMERIC. %BASIC-I-CDDSUBGRO, data type in CDD/Repository not supported, substituted group for: DECIMALSTRING::MY_UNSIGNED_NUMERIC. %BASIC-I-CDDSUBGRO, data type in CDD/Repository not supported, substituted group for: DECIMALSTRING::MY_LEF_SEP_NUMERIC. %BASIC-I-CDDSUBGRO, data type in CDD/Repository not supported, substituted group for: DECIMALSTRING::MY_LEFT_OVPNCH_NUMERIC. %BASIC-I-CDDSUBGRO, data type in CDD/Repository not supported, substituted group for: DECIMALSTRING::MY_RIGHT_SEP_NUMERIC. %BASIC-I-CDDSUBGRO, data type in CDD/Repository not supported, substituted group for: DECIMALSTRING::MY_RIGHT_OVPNCH_NUMERIC.
21.9.5. Other Data Types
- BIT
- DATE
- POINTER
- UNSPECIFIED
- VIRTUAL
- ALPHABETIC
VSI BASIC for OpenVMS does not support these data types. VSI BASIC for OpenVMS translates these data types by signaling the
informational message “Datatype in CDD/Repository not supported, substituted group
for: <field name>
”, and creates a group to contain
the field. See Table 21.2, “Unsupported CDD/Repository Data Types” for a description of how VSI BASIC for OpenVMS
translates these data types.
If you extract a CDD/Repository definition that contains a BIT field, the field must be a multiple
of 8 bits (1 byte). This means that the following field must be aligned on a byte
boundary. If the following field is not aligned on a byte boundary, VSI BASIC for OpenVMS signals the
error “Field <name>
from CDD/Repository has bit offset or
length.”
Chapter 22. Using DECwindows Motif Bindings with BASIC
This chapter explains the BASIC language exceptions for using standard DECwindows Motif Bindings. For more information about programming DECwindows Motif, see the DECwindows Motif Guide to Application Programming.
22.1. Overview of DECwindows Motif Concepts
This section introduces DECwindows Motif concepts. DECwindows Motif is an X Window System type of operating environment. DECwindows Motif is used on a workstation, where several windows can be displayed with different applications on each window.
To program in the DECwindows Motif environment, DECwindows Motif bindings are used to help write programs that create and manage the different resources needed to control the windowing environment.
22.2. Using DECwindows Motif Bindings with BASIC
The DECwindows Motif bindings consist of constant definitions, global variable declarations, record structures, and function prototypes. The bindings include everything that is needed to do windows programming using the DECwindows Motif Application Programming Interface (API).
The BASIC implementation of the DECwindows Motif bindings allow you to write to either the C version or the non-C version of the bindings. In either case, you will want to refer to the VMS DECwindows User Interface Language Reference Manual before you start programming. For information about using non-C bindings, see the DECwindows Motif for OpenVMS Guide to Non-C Bindings.
BASIC$HELLOMOTIF.BAS, and BASIC$HELLOBURGER.BAS supplied on the kit as examples of using the BASIC language for windows programming.
- Any identifiers longer than 31 characters must be truncated to 31 characters. Known instances include:
- S__XmTraverseObscuredCallbackStru (33)
- S_XmOperationChangedCallbackStruc (33)
- S_XmDragDropFinishCallbackStruct (32)
- Any identifiers beginning with an underscore must have the underscore dropped. Known instances include:
- _DXmPrintFormatStruct
- _DXmPrintOptionMenuStruct
- _XA_MOTIF_BINDINGS
- _XA_MOTIF_WM_FRAME
- _XA_MOTIF_WM_HINTS
- _XA_MOTIF_WM_INFO
- _XA_MOTIF_WM_MENU
- _XA_MOTIF_WM_MESSAGES
- _XA_MOTIF_WM_OFFSET
- _XA_MWM_HINTS
- _XA_MWM_INFO
- _XA_MWM_MESSAGES
- _XmSDEFAULT_BACKGROUND
- _XmSDEFAULT_FONT
- _XmSecondaryResuourceDataRec
- _XmTraverseObscuredCallbackStru
- _XtCheckSubclassFlag
- _XtIsSubclassOf
- The following list of identifiers are used either as both a data type and a field name or as a BASIC keyword. They cannot be used as is, but must have the suffix _D appended when used as a data type and the suffix _F appended when used as a field name.
- dimension
- display
- font
- name
- pixel
- screen
- size
- status
- substitution
- time
- value
- window
%INCLUDE DECW$MOTIF_DEFS.BAS before the subroutine statement
%INCLUDE DECW$MOTIF.BAS after it
22.3. DECwindows Motif Programming Examples Using BASIC
- Copy the needed files into your current directory:
$ COPY DECW$EXAMPLES:BASIC$HELLOMOTIF.* *.*
- Build the Resource (UID) file:
$ UIL/MOTIF BASIC$HELLOMOTIF.UIL
- Compile and link the BASIC program:
- Use the following example for DECWindows Motif V1.1:
$ BASIC BASIC$HELLOMOTIF $ LINK BASIC$HELLOMOTIF,SYS$INPUT/OPTIONS SYS$LIBRARY:DECW$DXMLIBSHR.EXE/SHARE SYS$LIBRARY:DECW$XMLIBSHR.EXE/SHARE SYS$LIBRARY:DECW$XTSHR.EXE/SHARE ^Z $
- Use the following example for DECWindows Motif V1.2:
$ BASIC BASIC$HELLOMOTIF $ LINK BASIC$HELLOMOTIF,SYS$INPUT/OPTIONS SYS$LIBRARY:DECW$DXMLIBSHR12.EXE/SHARE SYS$LIBRARY:DECW$MRMLIBSHR12.EXE/SHARE SYS$LIBRARY:DECW$XMLIBSHR12.EXE/SHARE SYS$LIBRARY:DECW$XTLIBSHRR5.EXE/SHARE ^Z $
You may want to create an options file with the previously mentioned shareable libraries in it.
- If you are not running on a workstation, make sure that your display is set correctly, for example:
$ SET DISPLAY/CREATE/NODE=xxxx
xxxx is the node name of a workstation with appropriate graphic capability.
- Run the application:
$ RUN BASIC$HELLOMOTIF
Note
The .UID file must be kept in the same directory as the .EXE file when run. This program looks in the current directory for the UID file.
Then follow the instructions in the dialog box.
22.4. Special Considerations for Handling Strings with DECwindows Motif
"A string" + "0"C
COMMON (c1) STRING hierarchy_file_name = 21 hierarchy_file_name = "BASIC$HELLOMOTIF.UID" + "0"C DECLARE LONG hierarchy_file_name_array(1) hierarchy_file_name_array(0) = LOC (hierarchy_file_name)
FUNCTION LONG ADDRESS_OF_STRING (STRING str_arg BY REF) OPTION TYPE=EXPLICIT, INACTIVE=SETUP END FUNCTION (LOC (str_arg))
DECLARE STRING temp_string temp_string = "A string value" + "0"C list_test = DXmCvtFCtoCS (ADDRESS_OF_STRING (temp_string), & byte_count, istatus)
Appendix A. Compile-Time Error Messages
This appendix describes compile-time and compiler command errors, their causes, and the user action required to correct them.
A.1. Compile-Time Errors
Indicates the program line that generated the error or errors.
Displays this program line.
Shows you the location of the error or errors and assigns a number to each location for future reference.
Displays the mnemonic, statement number within the line, the location number as previously displayed, and the message text. This is repeated for each error in the line.
%BASIC–<l>–<mnemonic>, <n>: <message>
<l>
I ---- indicating information
W ---- indicating a warning
E ---- indicating an error
F ---- indicating a severe error
<mnemonic>
Is a 3- to 9-character string that identifies the error. Error messages in this appendix are alphabetized by this mnemonic.
<n>:
Is the nth error within the line's picture.
<message>
Is the text of the error message.
Diagnostic on source line 1, listing line 1, BASIC line 10 10 DECLARE REAL BYTE A, A ........................1.......2 %BASIC--E--CONDATSPC, 1: conflicting data type specifications %BASIC--E--ILLMULDEF, 2: illegal multiple definition of name A
The error mnemonic CONDATSPC
Which error in the line's picture is referred to by the mnemonic
The message associated with that error
In this case, the error message tells you that there are two contradictory data-type keywords in the statement. The next line shows you the same type of information for the second error; in this case, the compiler detected multiple declarations of variable A.
If a compilation causes an error of severity I or W, the compilation continues and produces an object module. If a compilation causes an error of severity E, the compilation continues but produces no object module. If a compilation causes an error of severity F, the compilation aborts immediately.
The following is an alphabetized list of compilation error messages:
ACTARGMUS, actual argument must be specified
ERROR ---- A DEF function reference contains a null argument, for example, FNA(1,,2).
User action: Specify all arguments when referencing a DEF function.
ALLOCSML, allocated area may be too small for section
WARNING – A MAP or COMMON with the same name exists in more than one program module, and the first one encountered by the compiler is smaller than the subsequent ones.
User action: VSI BASIC first allocates MAP and COMMON areas in the main program, then MAP and COMMON areas in subprograms, in the order in which they were loaded. Thus, you can avoid this error by loading modules with the largest MAP or COMMON first. However, it is better practice to make MAP and COMMON areas equal in size.
AMBRECCOM, ambiguous RECORD component
ERROR – The program contains an ambiguous RECORD component reference, for example, A::D when both A::B::D and A::C::D exist.
User action: Remove the ambiguity by fully specifying the record component.
AMPCONILL, & continuation is illegal after %INCLUDE directive
2300 %INCLUDE %FROM %CDD "CDD$TOP.PERSONNEL.EMPLOYEE" & GOTO 3000
Ampersand continuation of the %INCLUDE directive is legal, however.
User action: Recode to eliminate the line continuation or use backslash continuation.
AMPCONREP, & continuation is illegal after %REPORT directive
2300 %REPORT %DEPENDENCY "CDD$TOP.PERSONNEL.EMPLOYEE.COURSE_FORM" & GOTO 3000
Ampersand continuation of the %REPORT directive itself is legal, however.
User action: Recode to eliminate the line continuation or use backslash continuation.
ANSDEFMUS, ANSI DEF must be defined before reference
ERROR – A program compiled with the /ANSI_STANDARD qualifier contains a reference to a DEF function before the function definition.
User action: Renumber the line containing the function definition so that the definition precedes all references to the function.
ANSILNREQ, a line number is required on first line for ANSI
ERROR – When you specify the /ANSI qualifier, a program must have a line number on the first line for the ANSI qualifier.
User action: Supply a line number on the first line.
ANSKEYSPC, keywords must be delimited by spaces in /ANSI
ERROR – A program compiled with the /ANSI_STANDARD qualifier contains a line where two elements (two keywords, a keyword and a line number, or a keyword and a string constant) are not separated by at least one space. For example, PRINT “Hello”.
User action: Delimit all keywords, line numbers, and string constants with at least one space.
ANSLINDIG, ANSI line number may not exceed 4 digits
ERROR – A program compiled with the /ANSI_STANDARD qualifier contains a line number with more than 4 digits, that is, a number greater than 9999.
User action: Renumber the program lines so that no line number exceeds 9999.
ANSLINNUM, ANSI line numbers must begin in column 1
ERROR – A program compiled with the /ANSI_STANDARD qualifier contains a line number preceded by one or more spaces or tabs.
User action: Remove any spaces and tabs that precede the line number.
ANSREQREA, ANSI requires REAL default type
ERROR – The /ANSI_STANDARD qualifier conflicts with the /TYPE_DEFAULT qualifier.
User action: Do not specify a default data type other than REAL. REAL is the default.
ANSREQSCA, ANSI requires SCALE 0
ERROR – The /ANSI_STANDARD qualifier conflicts with the /SCALE qualifier.
User action: Do not specify a scale factor.
ANSREQSET, ANSI requires SETUP
ERROR – The /ANSI_STANDARD qualifier conflicts with the /NOSETUP qualifier.
User action: Do not specify /NOSETUP.
ANYDIMNOT, dimension checking not allowed on ANY
ERROR – Both a data type of ANY and a DIM clause were specified in an EXTERNAL statement.
User action: Remove the DIM clause from the EXTERNAL statement. ANY implies either scalar or array.
ANYNOTALL, ANY not allowed on EXTERNAL PICTURE
ERROR – An attempt was made to specify the ANY keyword on an EXTERNAL PICTURE declaration. This is not allowed because the ANY data type should be used for calling non-BASIC procedures only.
User action: Remove the ANY keyword from the EXTERNAL PICTURE declaration.
APPMISNUM, append file missing line number on first line
ERROR – An attempt was made to append a source file that does not contain a line number on the first line.
User action: Put a line number on the first line of the appended file.
APPNOTALL, append not allowed on programs without line numbers
ERROR – The APPEND command cannot be used on a program without line numbers.
User action: Use an include file.
ARESTYMUS, area style must be “HOLLOW”, “SOLID”, “PATTERN”, or “HATCH”
ERROR – You specified an invalid value in the SET AREA STYLE statement.
User action: Specify one of the values listed in the message.
AREREQTHR, AREA output requires at least 3 X,Y points
ERROR – An AREA graphic output statement specifies less than 3 points.
User action: Specify at least 3 points in the AREA graphic output statement.
ARGERR, illegal argument for command
ERROR – An argument was entered for a command that does not take an argument, or an invalid argument was entered for a command, for example, SCALE A or LIST A.
User action: Reenter the command with the proper arguments.
ARRMUSHAV, array must have 1 dimension
ERROR – An array with multiple dimensions is specified where a one-dimensional array is required.
User action: Specify an array that has 1 dimension.
ARRMUSELE, array must have at least 4 elements
ERROR – You specified an array with less than four elements. This statement requires an array with at least four elements in it.
User action: Supply an array declared as having at least 4 elements.
ARRNAMREQ, array names only allowed
ERROR – The type of variable name required must be an array name.
User action: Change the variable name to an array name.
ARRNOTALL, array <name>
not allowed in
DEF declaration
ERROR – The parameter list for a DEF function definition contained an entire array.
User action: Remove the array specification. Passing an entire array as a parameter to a DEF function is not allowed.
ARRTOOBIG, named array <array-name>
is
too large
ERROR – An array must occupy fewer than (2^16 ---- 1) bytes of storage.
User action: Reduce the size of the array. If the array is within a record, the maximum size of the array is 65,535 bytes.
ATROVRVAR, attributes of overlaid variable
<name>
don't match
ERROR – A variable name appears in more than one overlaid MAP; however, the attributes specified for the variable are inconsistent.
User action: If the same variable name appears in multiple overlaid MAPs, the attributes (for example, data type) must be identical.
ATRPRIREF, attributes of prior reference to
<name>
don't match
WARNING – A variable or array is referenced before the MAP that declares it. The attributes of the referenced variable do not match those of the declaration.
User action: Make sure that the variable or array has the same attributes in both the reference and the declaration.
ATTGTRZER, graphics attribute value must be greater than zero
ERROR – You specified a negative value when a positive value is required.
User action: Supply a value greater than zero.
BADFMTSTR, invalid PRINT USING format string
ERROR – The PRINT USING format string specified is not valid.
User action: Supply a valid PRINT USING format string.
BADLOGIC, internal logic error detected
ERROR – An internal logic error was detected.
User action: This error should never occur. Please submit a Software Performance Report with a machine-readable copy of the source program.
BADNO, qualifier <name>
does not accept
’NO’
ERROR – A qualifier that does not allow a NO prefix was entered. For example, NODOUBLE.
User action: Select the proper qualifier.
BADPROGNM, error in program name
ERROR – The program name is longer than 39 characters or contains invalid characters.
User action: Change the program name to be less than or equal to 39 characters and make sure that it contains only letters, digits, dollar signs, and underscores.
BADVALUE, <text>
is an invalid keyword
value
FATAL – The command supplied an invalid value for a keyword.
User action: Supply a valid value.
BASICHLB, BASIC's HELP library is not installed on this system
INFORMATION – A HELP command was entered and the VSI BASIC HELP library was not available.
User action: See your system manager.
BIFREQNUM, built in function requires numeric expression
ERROR – A reference to a VSI BASIC built-in function contains a string instead of a numeric expression.
User action: Supply a numeric expression.
BIFREQSTR, built in function requires string expression
ERROR – The program specifies a numeric expression for a built-in function that requires a string argument.
User action: Supply a string expression for the built-in function.
BLTFUNNOT, built in function not supported
ERROR – The program contains a reference to a built-in function not supported by this version of VSI BASIC.
User action: Remove the function reference.
BOTBOUSPE, bottom boundary must be less than the top boundary
ERROR – In a statement that specifies a viewport or windowsize, you specified a bottom boundary that is greater than or equal to the corresponding top boundary.
User action: Correct the bottom boundary so that it is less than the top boundary.
BOUCANNOT, bound cannot be specified for array
EXTERNAL SUB XYZ (LONG DIM(1,2,3))
EXTERNAL SUB XYZ (LONG DIM(,,))
BOUMUSTBE, bounds must be specified for array
DECLARE LONG A(,)
DECLARE LONG A(50,50)
CANCON, can't continue
FATAL – A CONTINUE command was typed after changes had been made to the source code.
User action: After changes have been made to the source code, you can run the program, but you cannot continue it.
CAUNOTALL, CAUSE statement not allowed in error handler
ERROR – A CAUSE statement is specified within an error handler.
User action: Remove the CAUSE statement from the error handler.
CDDACCERR, CDD/Repository access error
ERROR – CDD/Repository detected an error on an attempted CDD/Repository record extraction. VSI BASIC displays the CDD/Repository error.
User action: Take action based on the associated CDD/Repository error.
CDDACCITE, CDD/Repository error while accessing item
<field-name>
of record
ERROR – CDD/Repository reported an error when accessing the field. The CDD/Repository record definition is corrupt, or there is an internal error in either VSI BASIC or CDD/Repository.
User action: If the problem is not in the CDD/Repository definition, please submit a software problem report (SPR) with the source code of a small program that produces this error.
CDDACCREC, CDD/Repository error while accessing record
ERROR – CDD/Repository reported an error when accessing the record. The CDD/Repository record definition is corrupt or there is an internal error in either VSI BASIC or CDD/Repository.
User action: If the problem is not in the CDD/Repository definition, please submit a software problem report (SPR) with the source code of a small program that produces this error.
CDDADJBOU, adjusted bounds for dimension
<number>
of
<array>
to be zero based
INFORMATION – CDD/Repository contains an array field with a lower bound that is not zero. VSI BASIC adjusts the bound so that the array is zero based.
User action: None.
CDDALCOFF, please submit an SPR ---- CDD/Repository
inconsistent with allocated offset for
<field-name>
FATAL – The offset of a field within a VSI BASIC RECORD differs from the offset specified by CDD/Repository for that record.
User action: Please submit a software problem report (SPR) with the source code of a small program that produces this error.
CDDALCSIZ, please submit an SPR ---- CDD/Repository
inconsistent with allocated size for
<field-name>
FATAL – The amount of storage allocated for a field in a VSI BASIC RECORD differs from the amount specified by CDD/Repository for that record.
User action: Please submit a software problem report (SPR) with the source code of a small program that produces this error.
CDDALCSPN, please submit an SPR ---- CDD/Repository
inconsistent with allocated span for
<field-name>
FATAL – The amount of storage allocated by a VSI BASIC RECORD for an array differs from the amount specified by CDD/Repository for that record.
User action: Please submit a software problem report (SPR) with the source code of a small program this error.
CDDAMBFLD, ambiguous field name <name>
for <RECORD--name>
ERROR – More than one CDDL structure share the same level and the same name.
User action: Change the CDD/Repository definition so that the structures have different names.
CDDATTBAS, CDD/Repository attributes for
<name>
are other than base 10
ERROR – A field in a CDD/Repository definition uses the BASE keyword. This warns you that the numeric field is not interpreted as a base 10 number.
User action: Remove the BASE attribute in CDD/Repository or avoid using the field.
CDDATTDAT, CDD/Repository data type attribute not permitted for GROUP
ERROR – A CDD/Repository definition specified a data type after the CDD/Repository STRUCTURE keyword. VSI BASIC translates STRUCTURE to a VSI BASIC RECORD or GROUP statement. These VSI BASIC statements do not allow data type attributes.
User action: Change the CDD/Repository definition.
CDDATTDIG, DIGITS attribute of
<field-name>
not supported for
datatype
INFORMATION – The field contains a CDD/Repository fixed-point data type that specifies the number of allowed digits. This warning tells you that VSI BASIC interprets the field as BYTE, WORD, LONG, or QUAD and does not support the DIGITS attribute for this data type.
User action: None.
CDDATTSCA, CDD/Repository specifies SCALE for
<RECORD-component>
. Not
supported.
INFORMATION – A field in a CDD/Repository definition uses the SCALE keyword. This warns you that the field has an implied exponent.
User action: Remove the SCALE attribute in CDD/Repository, or avoid using the field.
CDDATTTXT, CDD/Repository TEXT attribute for group
<group-name>
ignored
INFORMATION – A CDD/Repository record definition specifies a data type of TEXT for the entire record.
User action: None. VSI BASIC ignores the TEXT attribute and substitutes the UNSPECIFIED attribute.
CDDBASNAM, CDD/Repository specified BASIC name
<name>
has illegal form
ERROR – The VSI BASIC name specified in the CDD/Repository record definition is a reserved keyword or contains an illegal character.
User action: Change the invalid field name.
CDDBITFLD, field <field-name>
from
CDD/Repository has bit offset or length
ERROR – A CDD/Repository field does not start on a byte boundary.
User action: Change the bit field in CDD/Repository to have a length that is a multiple of 8 bits.
CDDCOLMAJ, <array-name>
from
CDD/Repository is a column major array
ERROR – An array specified in a CDD/Repository definition is column-major rather than row-major. Thus, it is incompatible with VSI BASIC arrays.
User action: Change the CDD/Repository definition to be a row-major array.
CDDDIGERR, decimal digits of <VALUE>
in
CDD/Repository out of range for
<field-name>
ERROR – A packed numeric CDD/Repository definition specifies more than 31 digits.
User action: Reduce the number of digits specified in the CDD/Repository definition.
CDDDIMNOT, RECORD cannot be dimensioned
ERROR – A CDD/Repository definition is itself an array. This is incompatible with VSI BASIC RECORDs, which can contain arrays but cannot be arrays.
User action: None. You cannot access CDD/Repository definitions that are arrays.
CDDDUPREC, RECORD <name>
from
CDD/Repository has duplicate name
ERROR – The CDD/Repository record name conflicts with a previous RECORD name. The previous RECORD name may be a standard VSI BASIC RECORD or another CDD/Repository record.
User action: Remove one of the duplicate definitions.
CDDFLDNAM, field name missing
ERROR – The CDD/Repository definition contains a field that is not named.
User action: Supply a field name for the CDD/Repository definition.
CDDINIIGN, initial value specified in CDD/Repository ignored for: name
INFORMATION – The specification of an initial value is unsupported by BASIC.
User action: Set the initial value of this field in your application program.
CDDINTONLY, % not allowed on <name>
with noninteger datatype
ERROR – The % suffix is allowed only on numeric data types.
User action: Remove the % suffix from the variable name or change the data-type keyword.
CDDLOWBOU, lower bound omitted for dimension
<number>
of
<array-name>
ERROR – An array in a CDD/Repository definition does not specify a lower bound.
User action: Check to make sure the omission is not a mistake. VSI BASIC supplies a lower bound of zero and continues after issuing this warning.
CDDMAXDIM, <array-name>
exceeds maximum
dimensions
ERROR – An array in a CDD/Repository definition specifies more than 32 dimensions.
User action: Reduce the number of dimensions in the CDD/Repository definition.
CDDNAMKEY, <name>
is a BASIC
keyword
ERROR – A CDD/Repository definition contains a field name that is a reserved word in VSI BASIC.
User action: Change the name in the CDD/Repository definition or supply a VSI BASIC name clause.
CDDOCCIGN, OCCURS DEPENDING ON clause for
<array-name>
from CDD/Repository ignored
INFORMATION – CDD/Repository contains an array field with a variable number of elements. VSI BASIC creates an array large enough for the maximum value.
User action: If you modify the array field, be sure also to change the field that contains the number of array elements.
CDDOFFERR, CDD/Repository offset error, field
<field-name>
offsets out of order
ERROR – The CDD/Repository definition has been corrupted or there is an internal error in either VSI BASIC or CDD/Repository.
User action: If the problem is not in the CDD/Repository definition, please submit a software problem report (SPR) with the source code of a small program that produces this error.
CDDPLUSERR, CDD/Repository access error
ERROR – CDD/Repository detected an error while attempting to record dependency data. VSI BASIC displays the CDD/Repository error.
User action: Take action based on the associated CDD/Repository error.
CDDPREERR, decimal precision in
CDD/Repository out of range for
<field-name>
ERROR – The number of fractional digits for a packed decimal field is greater than the total number of digits specified for that field.
User action: Change the number of fractional digits in CDD/Repository to be less than or equal to the total number of digits.
CDDRECFOR, CDD/Repository record format is not fixed
ERROR – CDD/Repository supports both variable and fixed-length records. VSI BASIC supports only fixed-length records.
User action: Change the CDD/Repository record definition to specify fixed-length.
CDDRECNAM, record from CDD/Repository does not have a record name
ERROR – VSI BASIC uses the field name of the outermost structure to name the record, and therefore cannot include a CDD/Repository record that does not provide a record name.
User action: Change the CDD/Repository record definition to provide a field name for the outermost structure of the record.
CDDSCAERR, decimal scale of
<scale-factor>
is out of range for
<field>
from CDD/Repository
ERROR – The scale factor for a packed decimal CDD/Repository field is greater than the number of digits in the field or less than zero.
User action: Change the scale factor in the CDD/Repository definition.
CDDSCAZER, scale 0 specified for CDD/Repository field
<field-name>
INFORMATION – A CDD/Repository field specifies no scale factor for a D_floating field, but the VSI BASIC program specifies a nonzero scale factor.
User action: Use a scale factor of zero in the VSI BASIC program.
CDDSTRONLY, $ not allowed on <name>
with nonstring datatype
ERROR – The $ suffix is only allowed on string data types.
User action: Remove the $ suffix from the variable name or change the data-type keyword.
CDDSUBGRO, substituted GROUP for
<field-name>
. Data type in CDD/Repository not
supported.
INFORMATION – The CDD/Repository definition specifies a data type that is not native to VSI BASIC. VSI BASIC creates a GROUP with the same name as the CDD/Repository field and creates variable names for the GROUP components.
User action: None.
CDDTAGIGN, tag value ignored for
<field-name>
from CDD/Repository
INFORMATION – The CDD/Repository record definition contains a VARIANTS OF.
User action: None. VSI BASIC translates the VARIANTS OF as if it were a regular variant; however, the tag value is ignored.
CDDUNSDAT, data type specified in CDD/Repository for
<field-name>
not supported
ERROR – The data type specified for a field is not supported by VSI BASIC.
User action: Change the data type in the CDD/Repository record definition.
CDDUPPBOU, upper bound omitted for dimension
<number>
of
<array-name>
ERROR – An array in a CDD/Repository definition does not specify an upper bound.
User action: Specify an upper bound in the CDD/Repository definition.
CDDVARFLD, field <name>
from
CDD/Repository has variable offset or length
ERROR – A CDD/Repository field can be either variable or fixed-length. VSI BASIC supports only fixed-length fields.
User action: Change the CDD/Repository definition.
CHAEXPMUS, channel expression must be numeric
ERROR – The program contains a nonnumeric channel expression, for example, PUT #A$
User action: Change the channel expression to be numeric.
CHALINCLA, CHAIN does not support line number clause
ERROR – A CHAIN statement contains a LINE keyword and a line number argument.
User action: Remove the LINE keyword and the line number argument.
CHANOTALL, CHANGES not allowed on primary key
ERROR – The PRIMARY KEY clause in an OPEN statement specifies CHANGES.
User action: Remove the CHANGES keyword; you cannot change the value of a primary key.
CHASTAAMB, CHANGE statement is ambiguous
ERROR – A string variable and a numeric array have the same name in a CHANGE statement.
User action: Change the name of the string variable or the numeric array.
CLIPMUSBE, clipping must be set to “ON” or “OFF”
ERROR – You specified an invalid value in the SET CLIP statement.
User action: Specify one of the values listed in the message.
CLOSEIN, error closing <file-name>
as
input
ERROR – An error was detected while closing an input file.
User action: Take corrective action based on the associated message.
CLOSEOUT, error closing <file-name>
as
output
ERROR – An error was detected while closing an output file.
User action: Take corrective action based on the associated message.
CMDNOTALL, command not allowed on programs without line numbers
ERROR – A command that cannot be used on a program without line numbers has been used on a program without line numbers.
User action: Do not use this command on programs without line numbers.
CODLENEST, internal code length estimate error. Submit an SPR
FATAL – VSI BASIC has incorrectly estimated the size of the generated code for your program.
User action: Submit a software problem report (SPR) with the program that caused the error. (You can often work around this error by making a simple change to your code.)
COLOUTRAN, color intensities must be in the range 0.0 to 1.0
ERROR – The value specified for color intensity is either less than 0.0 or greater than 1.0.
User action: Supply a value from 0.0 to 1.0.
COMMAPALI, variable <name>
not aligned
in COMMON/MAP <name>
INFORMATION – In a COMMON or MAP, the total storage preceding a REAL, WORD, LONG, or QUAD numeric variable is an odd number of bytes.
User action: None. In VSI BASIC, numeric data can start on any byte boundary.
COMMAPNEQ, COMMON/MAP area sizes are not equal for section
WARNING – A MAP or COMMON with the same name exists in more than one program module, but the size of the areas differs.
User action: Make the size of the COMMON or MAP areas equal in size in all modules.
COMMAPOVF, COMMON/MAP <name>
is too
large
ERROR – The program contains a MAP or COMMON longer than (2^31 ---- 1) longwords.
User action: Reduce the length of the COMMON or MAP.
CONCOMSYN, conditional compilation cannot be used with /SYNTAX
FATAL – The /SYNTAX_CHECKING qualifier is in effect when a program line containing the %IF, %THEN, %ELSE, or %END %IF lexical directive was entered.
User action: Turn off syntax checking before entering a program line containing the %IF, %THEN, %ELSE, or %END %IF lexical directive.
CONDATSPC, conflicting data type specifications
ERROR – The program contains a declarative statement containing two or more consecutive and contradictory data-type keywords, for example, DECLARE REAL BYTE.
User action: Remove one of the data-type keywords or make sure that the keywords refer to the same generic data type. For example, DECLARE REAL SINGLE is valid.
CONEXPREQ, constant expression required
ERROR – A statement specifies a variable, built-in function reference or exponentiation where a constant is required.
User action: Supply an expression containing only literals or declared constants or remove the exponentiation operation.
CONTARNOT, CONTINUE target not legal in detached error handlers
ERROR – A CONTINUE statement within a detached WHEN block error handler contains a target.
User action: Remove the target line number or label from the CONTINUE statement or use an attached error handler.
CONIS_INC, constant is inconsistent with the type of
<name>
ERROR – A DECLARE CONSTANT statement specifies a value that is inconsistent with the data type of the constant, for example, a BYTE value specified for a REAL constant.
User action: Change the declaration so that the data type of the value matches that of the constant.
CONIS_NEE, <item>
requires conditional
expression
ERROR – A CASE or IF keyword is immediately followed by a floating-point or string expression.
User action: Supply a conditional expression (relational, logical, or integer).
CONLFTSID, constant <name>
not allowed
on left side of assignment
ERROR – The program tries to assign a value to a user-defined constant.
User action: Remove the assignment statement; once you have assigned a value to a declared constant, you cannot change it.
CONNOTALL, constant <name>
not allowed
in assignment context
ERROR – The program tries to assign a value to a user-defined constant.
User action: Remove the assignment statement; once you have assigned a value to a declared constant, you cannot change it.
COOMUSBE, coordinates must be within NDC space (0.0 to 1.0)
ERROR – The value of a coordinate is either less than 0.0 or greater than 1.0.
User action: Supply a value from 0.0 to 1.0.
CORSTAFRA, corrupted stack frame
ERROR – An immediate mode statement was entered after a STOP statement was executed in the VAX BASIC Environment and something corrupted the stack.
User action: Check program logic to make sure that all array references are within array bounds. This error can also be caused by loading non-BASIC object modules in the VAX BASIC Environment.
COUONLALO, COUNT clause only allowed with array LIST clause
ERROR – A COUNT clause was found on a SET INITIAL CHOICE statement that contains a LIST clause that does not contain a string array.
User action: Remove the COUNT clause or use the array form of the LIST clause.
COUVALCAN, COUNT value cannot be greater than array size
ERROR – In the COUNT clause, you specified a count that is larger than the size of the array that you supplied.
User action: Change either the COUNT value or the size of the array so that COUNT is less than or equal to the number of elements in the array.
DATTYPEXP, data type required for variable
<name>
with /EXPLICIT
ERROR – A program compiled with the /TYPE=EXPLICIT qualifier declares a variable without specifying a data type.
User action: Supply a data-type keyword for the variable or compile the program without the /TYPE=EXPLICIT qualifier.
DATTYPNOT, data type keyword not allowed in SUB statement
ERROR – A SUB statement contains a data-type keyword between the subprogram name and the parameter list.
User action: Remove the data-type keyword. In a SUB statement, data-type keywords can appear only within the parameter list.
DATTYPREQ, data type required in EXTERNAL CONSTANT declaration
ERROR – An EXTERNAL CONSTANT statement has no data-type keyword.
User action: Supply a data-type keyword to specify the data type of the external constant.
DECIMERR, DECIMAL overflow
WARNING – The program contains a DECIMAL expression whose value is outside the valid range.
User action: Reduce the value of the DECIMAL expression.
DECLEXSYN, DECLARED lexical function syntax error
ERROR – The syntax of the %DECLARED lexical function is specified incorrectly.
User action: Supply the correct syntax.
DECPREOUT, DECIMAL precision specification out of range
ERROR – In the declaration for a packed decimal variable or constant, the number of digits to the right of the decimal point is greater than the total number of digits specified, or greater than 31.
User action: Change the declaration so that the total number of digits specified is less than 31, and the number of digits to the right of the decimal point is less than or equal to the total number of digits.
DECSIZOUT, DECIMAL size specification out of range
ERROR – The declaration for a packed decimal variable or variable specifies more than 31 digits.
User action: Change the declaration to specify 31 or fewer digits.
DEFEXPCOM, expression with DEF* too complex, moving
<name>
invocation
WARNING – A DEF* is being invoked from within a complex expression. To simplify the expression, the compiler will evaluate the DEF*(s) first. (Alpha BASIC only.)
User action: Rewrite statement into simpler expressions.
DEFINVNOT, DEF invocation not allowed in assignment context
ERROR – A DEF function invocation (including a parameter list) appears on the left side of an assignment statement.
User action: Remove the assignment statement. You cannot assign values to a function invocation.
DEFMODNOT, DEF <name>
mode not as
declared
ERROR – The specified data type in a function declaration disagrees with the data type specified in the function definition.
User action: Make the data-type specifications match in both the function declaration and the function definition.
DEFNOTDEF, DEF <name>
not
defined
ERROR – The program contains a reference to a nonexistent user-defined function.
User action: Define the function in a DEF statement.
DEFNOTWHE, DEF not allowed in WHEN block or handler
ERROR – A DEF function definition is not allowed in a WHEN block or its associated handler.
User action: Remove the DEF function definition from within the WHEN block or handler.
DEFRESREF, DEF <name>
result reference
illegal in this context
ERROR – The program attempts to assign a value to a DEF name outside the DEF block.
User action: Remove the assignment statement. You cannot assign a value to a DEF outside of the DEF block.
DEFSIZNOT, DEF <name>
decimal size not
as declared
ERROR – The DECIMAL(d,s) size specified in the DEF statement does not match the DECIMAL(d,s) used in the associated DECLARE DEF statement.
User action: Make the DECIMAL size specification agree in both the DECLARE DEF and DEF statements.
DEFSTAPAR, DEF* formal <formal-name>
inconsistent with usage outside DEF*
ERROR – A DEF* formal parameter has the same name as a program variable, but different attributes.
User action: You should not use the same names for DEF* parameters or program variables. If you do, you must ensure that they have the same data type and size.
DEFSTOOCMPX, DEF* <name>
too complex to
compile
ERROR – A DEF* function uses too many temporary variables or parameters, or is too complex to compile.
User action: Simplify and/or break the function into smaller pieces.
DEFSTRPAR, DEF string parameter is illegal in MAP DYNAMIC or REMAP
ERROR – You cannot use a static string that is a parameter declared in a DEF or DEF* function as the storage area in a MAP DYNAMIC or REMAP statement.
User action: Change the storage area specification in the MAP DYNAMIC or REMAP statement to use either a MAP name or a static string variable that is not a parameter to the DEF or DEF* function.
DELETE, ignoring <item>
ERROR – The program contains a syntax error. The compiler tries to recover from the error by ignoring an operator or separator in the source line. For example, DIM A(3, ) is a syntax error, but VSI BASIC continues the compilation by ignoring the comma. The compilation continues only in order to discover other errors; no object module is produced.
User action: Correct the syntax error in the displayed line.
DEPNOTANS, /DEPENDENCY_DATA qualifier not allowed with /ANSI
ERROR – The /DEPENDENCY_DATA qualifier conflicts with the /ANSI_STANDARD qualifier.
User action: Specify either the /DEPENDENCY_DATA qualifier or the /ANSI_STANDARD qualifier, but not both.
DESCOMABORT, /DESIGN=COMMENT processing has been aborted due to an internal error – please submit an SPR
INFORMATION – The compiler was unable to process comment information due to an internal error.
User action: Please submit a software problem report (SPR) with the source code of a small program that produces the error.
DESCOMERR, error in processing design information
WARNING – The design information was syntactically incorrect.
User action: You should respecify the design information and compile the program again.
DESIGNTOOOLD, /DESIGN=COMMENT processing routines are too old for the compiler
WARNING – The compiler encountered obsolete routines.
User action: Install a new version of the Language Sensitive Editor for OpenVMS.
DESOUTRAN, destination out of range
FATAL – The branch destination in an ON GOSUB statement is greater than 32,767 bytes away from the statement.
User action: Reduce the distance between the destination and the statement.
DIMOUTRAN, dimension is out of range
ERROR – The program contains the declaration of an array that specifies a negative number as a dimension.
User action: Change the dimension to a positive number.
DIMLSSZERO, dimension must be greater than zero
ERROR – The number specified for a dimension must be greater than zero.
User action: Change the number to be greater than zero.
DIMTOOBIG, dimension for array <name>
must be between 1 and <number>
ERROR – The number of the dimension specified is greater than the number of dimensions in the array.
User action: Change the dimension number to be less than or equal to the number of dimensions in the array.
DIRMUSTBE, directive must be only item on line
ERROR – The program contains a compiler directive that is not the only item on the line.
User action: Place the directive on its own line.
DIRNOTIMM, directive not valid in immediate mode
ERROR – A compiler directive was typed in the VAX BASIC Environment.
User action: None. Compiler directives are invalid in immediate mode.
DIVBY_ZER, division by zero
WARNING – The value of a number divided by zero is indeterminate.
User action: Change the expression so that no expression is divided by the constant zero.
DRAWITREQ, DRAW WITH clause requires 4X4 matrix
ERROR – A user matrix is specified in a DRAW statement WITH clause where a two-dimensional matrix with lower bounds 0 and upper bounds 4 in both dimensions is required.
User action: Declare the matrix to be a two-dimensional matrix with lower bounds 0 and upper bounds 4 in both dimensions.
DUPCLASPE, duplicate clause specified
ERROR – A duplicate clause was found on a SET INITIAL statement or a graphics input statement.
User action: Remove the duplicate clause.
DUPLINNOT, duplicate line numbers not ANSI
ERROR – A program compiled with the /ANSI_STANDARD qualifier from the DCL command level, or called into the VAX BASIC Environment with the OLD command while the /ANSI_STANDARD qualifier is in effect, contains two identical line numbers.
User action: Remove one instance of the duplicate line number. Even if you compile the program without the /ANSI_STANDARD, VSI BASIC will ignore all statements connected with the first instance of the duplicate line number before compiling the program.
DUPLNFND, duplicate line number
<number>
found
INFORMATION or WARNING
INFORMATION – A line number in an include file is the same as a line number in the main source file.
WARNING – There are two lines in the main source file with the same line number. VSI BASIC keeps the second occurrence of the line number.
User action: Correct the source by changing one of the line numbers to an unused number.
DYNATTONL, DYNAMIC attribute only valid for MAP areas
ERROR – A COMMON keyword is followed by the DYNAMIC keyword.
User action: Remove the DYNAMIC keyword. The DYNAMIC attribute is valid only for MAP areas.
DYNSTRINH, dynamic string variable
<name>
inhibits optimization
INFORMATION – This error is reported only when the /NOSETUP qualifier is in effect. The program contains a dynamic string variable. This prevents optimization of the compiler-generated code.
User action: Place the string variable in a COMMON keyword or MAP area.
ELENOALGN, Elements within array
<array-name>
are not naturally
aligned.
WARNING – Identifies record arrays that may not be naturally aligned because the size of each record element is not a multiple of the record's natural alignment. This error is reported only when the /WARNING=ALIGNMENT qualifier is in effect.
User action: Modify the size of the record to be a multiple of the record's natural alignment.
ELSIMPCON, ELSE appears in improper context, ignored
ERROR – The program contains an ELSE clause that either is not preceded by an IF statement or that appears after an IF has been terminated with a line number or END IF.
User action: Remove either the ELSE clause or the terminating line number or END IF.
EMPTYOBJ, Empty object file due to error
INFORMATION – The compiler has detected errors and therefore did not produce an object file.
User action: The errors must be corrected before the compiler will produce an object file.
ENDIMPCON, END IF appears in improper context, ignored
ERROR – The program contains an END IF statement that either is not preceded by an IF statement or occurs after an IF has been terminated by a line number.
User action: Supply an IF statement or remove the terminating line number.
ENDSTAREQ, END statement required in ANSI
INFORMATION – A program compiled with the /ANSI_STANDARD qualifier does not contain an END statement.
User action: Include an END statement as the last statement in the program. ANSI Minimal BASIC requires an END statement.
ENTARRFIE, entire array field of virtual record cannot be passed
The array is an item in a record
The record is itself dimensioned as a virtual array
User action: Assign the values of the array to another array that is of the same data type and dimension but that is not a field of a virtual array record, and pass the second array as the parameter.
ENTARRNOT, entire array not allowed in this context
ERROR – The program specifies an entire array in a context that permits only array elements, for example, in a PRINT statement.
User action: Remove the reference to the entire array.
ENTGRONOT, entire GROUP or RECORD not allowed in this context
ERROR – The program specifies an entire GROUP or RECORD in a context that permits only GROUP or RECORD components, for example, PRINT ABC::XYZ where XYZ is a GROUP.
User action: Remove the reference to the entire GROUP or RECORD.
ENTVIRARR, entire virtual array cannot be a parameter
ERROR – The program attempts to pass an entire virtual array as a parameter.
User action: None. You cannot pass an entire virtual array as a parameter.
EOLNOTTER, End of line does not terminate IFs due to active blocks
ERROR – A THEN or ELSE clause contains a loop block, and a line number terminates the if-then-else before the end of the loop block.
User action: Make sure that any loop is entirely contained in the THEN or ELSE clause.
ERLNOTALL, ERL statement not allowed in programs without line numbers
ERROR – An ERL statement has been found in a program without line numbers.
User action: Remove the ERL statement.
ERRACCLIB, error accessing module
<mod-name>
in text library
<text-lib-name>
ERROR – VSI BASIC found an unexpected LIBRARIAN error while trying to %INCLUDE a text library module. This error message is followed by a specific LIBRARIAN (LBR) message.
User action: Take appropriate action based on the associated LBR message.
ERRCLOLIB, error closing text library
<text-lib-name>
ERROR – The text library specified in a %INCLUDE directive could not be closed. This error message is followed by the specific LIBRARIAN (LBR) error.
User action: Take appropriate action based on the associated LBR message.
ERROPEFIL, error opening file
ERROR – The file specified in a %INCLUDE directive could not be opened. This error message is followed by the specific RMS error.
User action: Take appropriate action based on the associated RMS error.
ERROPELIB, error opening text library
<text-lib-name>
ERROR – The text library specified in a %INCLUDE directive could not be opened. This error message is followed by the specific LIBRARIAN (LBR) error.
User action: Take appropriate action based on the associated LBR message.
ERRREADFIL, error reading file
<file_name>
ERROR – the compiler encountered problems while reading either a BASIC source file or a CDD audit file (as specified using the /AUDIT qualifier).
User action: Examine the secondary message that follows this message to find out what went wrong, then take the appropriate action.
ERRRECCOM, erroneous RECORD component
ERROR – The program contains an erroneous record component, for example, specifying A::B when RECORD A has no component named B.
User action: Remove the erroneous reference.
EXEDIMILL, executable DIMENSION illegal for static array
ERROR – A DIMENSION statement names an array already declared with a DECLARE, COMMON, MAP, or RECORD statement, or one that was declared statically in a previous DIMENSION statement.
User action: Remove the executable DIMENSION statement or originally declare the array as executable in a DIMENSION statement.
EXPDECREQ, explicit declaration of
<name>
required
ERROR – The program is compiled with the /TYPE:EXPLICIT qualifier in effect, and the program references a variable, constant, function, or subprogram name that is not explicitly declared.
User action: Explicitly declare the variable, constant, function, or subprogram.
EXPIFDIR, expecting IF directive
ERROR – The program contains a %END that is not immediately followed by a %IF.
User action: Supply a %IF immediately following the %END.
EXPNOTALL, expression not allowed in this context
ERROR – The program contains an expression in a context that allows only simple variables, array elements, or entire arrays, for example, in FIELD and MOVE statements.
User action: Remove the expression.
EXPNOTRES, expression does not contribute to result of string concatenation
INFORMATION – The compiler has detected an expression that is not needed in determining a result.
User action: Review the program to determine if the expression can be eliminated. You may want to remove the expression if it is determined to be unnecessary.
EXPTOOCOM, expression too complicated
ERROR – The program contains an expression or statement too complicated to compile. This message can occur whenever VSI BASIC is unable to allocate sufficient registers.
User action: Recode as required; for example, rewrite the statement as two or more less complicated statements.
EXPUNAOPE, expecting unary operator or legal lexical operand
ERROR – A compiler directive contains an invalid lexical expression, for example, %IF *3% %THEN.
User action: Correct the lexical expression.
EXTELSFOU, extra ELSE directive found
ERROR – The program contains a %ELSE directive that is not matched with a %IF directive.
User action: Make sure that each %ELSE is preceded by a %IF, and that each %IF contains no more than one %ELSE clause.
EXTENDIF, extra END IF directive found
ERROR – A program unit contains a %END %IF without a preceding %IF directive.
User action: Supply a %IF for the %END %IF.
EXTLEFPAR, extra left parenthesis in expression
ERROR – A compiler directive contains a lexical expression with an extra left parenthesis.
User action: Remove the extra parenthesis.
EXTNAMTOO, EXTERNAL name too long, truncating to
<new--name>
WARNING – An EXTERNAL statement names a symbol longer than 31 characters.
User action: Shorten the symbol name to 31 characters or less.
EXTRIGPAR, extra right parenthesis in expression.
ERROR – A compiler directive contains a lexical expression with an extra right parenthesis.
User action: Remove the extra parenthesis.
EXTSTRVAR, EXTERNAL STRING variables not supported
ERROR – The program contains an EXTERNAL statement that specifies an external string variable.
User action: Remove or change the EXTERNAL statement. VSI BASIC does not support external string variables.
FEANOTANS, language feature not ANSI
INFORMATION – A program compiled with the /ANSI_STANDARD qualifier contains a VSI BASIC feature (such as a long variable name or a string array) that does not conform to the ANSI Minimal BASIC Standard. (See Chapter 5, Simple Input and Output for more information about the ANSI Minimal Standard).
User action: Although VSI BASIC allows you to run programs with non-ANSI language features, you must remove these features if you want your program to be transportable to other ANSI Minimal BASIC compilers.
FEANOTAVA, language feature not available in Alpha BASIC
Feature is not currently available in Alpha BASIC.
User action: Rewrite code to work around unavailable feature.
FIEVALONL, FIELD valid only for dynamic string variables
ERROR – A FIELD statement contains a numeric or fixed-length string variable.
User action: Remove the numeric or fixed-length string variable. Only dynamic string variables are valid in FIELD statements.
FILACCERR, file access error for INCLUDE directive
<file-name>
ERROR – The file named in the %INCLUDE directive was correctly opened but could not be read for some reason, for example, the disk drive was switched off line.
User action: Take action based on the associated RMS error messages.
FILEWRITE, <prog--name>
written to
file: <file-name>
INFORMATION – The specified program name has been saved in file-name.
User action: None.
FILNOTALL, FILL not allowed in MAP DYNAMIC
ERROR – A MAP DYNAMIC statement contains a FILL item.
User action: Remove the FILL item.
FILNOTDEL, error deleting
<file-name>
ERROR – An error was detected in attempting to delete a file.
User action: Supply a valid file specification, or take corrective action based on the associated message.
FILTOOBIG, FILL number <n>
in overlay
<m>
of MAP
<name>
too big
ERROR – A FILL string length or repeat count caused the compiler to try to allocate more than 2^31 longwords of storage.
User action: Check the specified MAP statement and change the FILL string length or repeat count.
FLDNOALGN, FIELD <field-name>
within
RECORD <record_name>
is not naturally
aligned.
WARNING – Identifies a field within a record that was found not to be naturally aligned. This error is reported only when the /WARNING=ALIGNMENT qualifier is in effect.
User action: Modify the record so that all fields are naturally aligned.
FLOCVTILL, floating CVT valid only for SINGLE and DOUBLE
ERROR – A CVTF$ or CVT$F function names a GFLOAT, HFLOAT, SFLOAT, TFLOAT, or XFLOAT value as an argument, or the default real size is one of these.
User action: Use a SINGLE argument rather than SFLOAT. Use a DOUBLE argument rather than GFLOAT, TFLOAT, HFLOAT, or XFLOAT.
FLOPOIERR, floating point error or overflow
WARNING – The program contains a numeric expression whose value is outside the valid range for the default floating-point data type.
User action: Modify the expression so that its value is within the allowable range or select as the default REAL size a floating-point data type that has a greater range.
FNEWHINOT, exit from DEF while not in DEF
ERROR – An FNEXIT or EXIT DEF statement has no preceding DEF statement.
User action: Define the function before inserting an FNEXIT or EXIT DEF statement.
FNEWITDEF, end of DEF seen while not in DEF
ERROR – An FNEND or END DEF statement has no preceding DEF statement.
User action: Define the function before inserting an FNEND statement or delete the FNEND statement.
FORFEEMUS, FORM FEED must appear at end of line
INFORMATION – A form-feed character is followed by other characters in the same line.
User action: Remove the characters following the form feed. A form feed must be the last or only character on a line.
FORPARMUS, formal parameter must be supplied for
<name>
ERROR – The declaration of a DEF, SUB, or FUNCTION routine contains the parentheses for a parameter list but no parameters.
User action: Supply a parameter list or remove the parentheses.
FORSTRPAR, formal string parameters may not be FIELDed
ERROR – A variable name appears both in a subprogram formal parameter list and a FIELD statement in the subprogram.
User action: Remove the variable from the FIELD statement or the parameter list.
FOUENDWIT, found end of <block>
without
matching <item>
ERROR – The program contains an END SELECT, END DEF, END FUNCTION, FUNCTIONEND, SUBEND, END SUB, or END IF without a matching SELECT, DEF, SUB, FUNCTION, or IF.
User action: Supply a SELECT, DEF, FUNCTION, SUB, or IF to
match the END <block>
statement, or remove the
erroneous END statement.
FOUND, found <item>
when expecting
<item>
ERROR – The program contains a syntax error. VSI BASIC displays the item where the error was detected, then displays one or more items that make more sense in that context. The compilation continues so that other errors can be detected. The actual program line remains unchanged and no object file is produced.
User action: Examine the line carefully to discover the error. Change the program line to correct the syntax error.
FOUNXTWIT, found NEXT without matching WHILE or UNTIL
ERROR – The program contains a NEXT statement without a corresponding WHILE or UNTIL statement.
User action: Supply a WHILE or UNTIL statement or remove the erroneous NEXT statement.
FOUWITMAT, found NEXT without matching FOR
ERROR – The program contains a NEXT
<control--variable>
statement without a
matching FOR
<control--variable>
statement.
User action: Supply a FOR statement or remove the erroneous NEXT statement.
FUNINVNOT, function invocation not allowed in assignment context
ERROR – An external function invocation (including a parameter list) appears on the left side of an assignment statement.
User action: Remove the assignment statement. You cannot assign values to a function invocation.
FUNNESTOO, function nested too deep
ERROR – The program contains too many levels of function definitions within function definitions.
User action: Reduce the number of nested functions.
FUNWHINOT, exit from FUNCTION while not in FUNCTION
ERROR – An EXIT FUNCTION or FUNCTIONEXIT statement was found in a module that is not a FUNCTION subprogram.
User action: Remove the EXIT FUNCTION or FUNCTIONEXIT statement.
GRAARRMUS, graphics array must be integer or real
ERROR – The specified array has a data type other than an integer or real data type.
User action: Declare the array with an integer or real data type.
HANNOTDEF, HANDLER not allowed in DEF
ERROR – A HANDLER definition has been found within a DEF function definition.
User action: Remove the HANDLER definition from inside the DEF function definition.
HANNOTFOU, error handler <name>
not
found
ERROR – You did not define the HANDLER you referenced in a WHEN statement.
User action: Define the HANDLER you reference in the WHEN statement.
HANNOTWHE, HANDLER not allowed in a WHEN block or handler
ERROR – A detached HANDLER definition was found in a WHEN block protected region or associated handler.
User action: Remove the HANDLER definition from within all WHEN block protected regions and associated handlers.
HANWHINOT, exit from HANDLER while not in HANDLER
ERROR – An EXIT HANDLER statement was found while not in a HANDLER block.
User action: Remove the EXIT HANDLER statement.
HFLOATNOTS, HFLOAT is not supported
ERROR – HFLOAT floating-point data type is not supported by Alpha BASIC.
User action: Remove the use of HFLOAT floating-point data type, substituting either GFLOAT, TFLOAT, or XFLOAT as appropriate.
HORJUSMUS, horizontal justification must be “LEFT”, “CENTER”, “RIGHT” or “NORMAL”
ERROR – You specified an invalid value for the horizontal component of the SET TEXT JUSTIFY statement.
User action: Specify one of the values listed in the message.
IDEMAYAPP, IDENT directive may appear only once per module
WARNING – The program contains more than one %IDENT compiler directive.
User action: Remove all but one %IDENT directive.
IDENAMTOO, IDENT directive name is too long
WARNING – The quoted string in a %IDENT directive is too long.
User action: Reduce the length of the string. The maximum length is 31 characters.
IF_EXPMUS, IF directive expression must be terminated by THEN directive
ERROR – A %IF directive contains a %ELSE clause with no intervening %THEN clause.
User action: Insert a %THEN clause.
IF_IN_INC, IF directive in INCLUDE directive needs END IF directive in same file
ERROR – A %INCLUDE file contains a %IF but no %END %IF.
User action: Supply a %END %IF for the %INCLUDE file.
IF_NOTTER, IF statement not terminated
ERROR – The program contains an if-then-else statement within a block (for example, a FOR-NEXT, SELECT-CASE, or WHILE block) and the end of the block was reached before the if-then-else statement was terminated.
User action: Check program logic to be sure if-then-else statements are terminated with a line number or an END IF statement before the end of the block is reached.
ILLALLCLA, illegal ALLOW clause
<clause>
ERROR – The program contains an ALLOW clause on a GET statement, and the file was not opened with the UNLOCK EXPLICIT clause.
User action: Either remove the ALLOW clause from the GET statement or use the UNLOCK EXPLICIT clause in the OPEN statement.
ILLARGBP2, illegal argument count for BASIC-PLUS-2
INFORMATION – The program contains a SUB, DEF, or EXTERNAL FUNCTION reference with more than 32 parameters. This error is reported only when the /FLAG:BP2COMPATIBILITY qualifier is in effect.
User action: If the program must run under both VSI BASIC and PDP–11 BASIC-PLUS-2, the function must have 32 or fewer parameters.
ILLARGPAS, illegal argument passing mechanism
ERROR – The program specifies an invalid argument-passing mechanism, for example, passing strings or arrays BY VALUE, or passing an entire virtual array.
User action: Check all elements for the proper parameter-passing mechanism.
ILLCALFUN, illegal CALL of a DECIMAL, HFLOAT or STRING function
ERROR – You attempted to use the CALL statement to invoke either a DECIMAL, HFLOAT, or STRING function.
User action: Invoke the function not using the CALL statement.
ILLCHA, illegal character <ASCII
code>
WARNING – The program contains illegal or incorrect characters.
User action: Examine the program for correct usage of the VSI BASIC character set and possibly delete the character.
ILLCHAEXT, illegal character <ASCII
code>
in external name
ERROR – The external symbol in an EXTERNAL FUNCTION or CONSTANT declaration contains an invalid character.
User action: Remove the invalid character. External names can use only printable ASCII characters: ASCII values in the range 32 to 126, inclusive.
ILLCHAIDE, illegal character <ASCII
value>
in IDENT directive
WARNING – A %IDENT directive contains an illegal character with the reported ASCII value.
User action: Remove the illegal character.
ILLCONTYP, illegal constant type
ERROR – The program contains an invalid declaration, for example, DECLARE RFA CONSTANT.
User action: Remove the invalid data type. You cannot declare constants of the RFA data type.
ILLEXTPDP, <name>
is illegal as a
PDP–11 external name
INFORMATION – This error is reported only when the /FLAG=BP2COMPATIBILITY qualifier is in effect. The external name is longer than six characters or contains a non-RAD50 character.
User action: Reduce the length of the name or remove the non-RAD50 character.
ILLFRMNAM, illegally formed name
ERROR – The program contains an invalid user identifier (such as a variable, constant, or function name).
User action: Change the name to comply with the rules for naming user identifiers. See the VSI BASIC Reference Manual for more information.
ILLFRMNUM, illegally formed numeric constant
ERROR – The program contains either: 1) an invalid E-format expression, or 2) a numeric constant with a digit that is invalid in the specified radix, for example, a decimal constant containing a hexadecimal digit.
User action: Supply a valid E-format expression or a constant that is valid in the specified radix.
ILLGOTO, can't GOTO outside current procedure
WARNING – The target line number of an immediate mode GOTO statement is outside of the currently compiled procedure.
User action: None. If you RUN a source file containing more than one program unit, the currently compiled program is the last program unit in the source file. If you use the OLD command to read a program into memory and load one or more object modules, then type RUN, the currently compiled procedure is the program you read into memory with OLD.
ILLIDEPDP, illegal %IDENT string for PDP–11
INFORMATION – A %IDENT compiler directive contains a string that is invalid for PDP–11 systems. This error is issued only when the BP2 compatibility flagger is enabled.
User action: Change the %IDENT string. The string must be from 1 to 6 characters, and must contain only RAD-50 characters.
ILLIO_CHA, illegal I/O channel
ERROR – A constant channel expression is greater than 99, or a variable channel expression is greater than 119.
User action: If the channel expression is a constant, change to be less than or equal to 99. A variable channel expression can be less than or equal to 119; however, channels in the range 100 to 119 are reserved for programs using LIB$GET_LUN.
ILLLINNUM, illegal line number in CHAIN
ERROR – A CHAIN with LINE statement specifies an invalid line number. Either the number is outside the valid range, or a string expression follows the LINE keyword.
User action: Supply an integer line number from 1 to 32,767, inclusive.
ILLLOCARG, illegal LOC argument
ERROR – An argument to the LOC function is a constant, virtual array element, or expression.
User action: Change the argument to the LOC function.
ILLLOONES, illegal loop nesting, expecting NEXT
<VARIABLE>
ERROR – The program contains overlapping loops.
User action: Examine the program logic to make sure that the FOR and NEXT statements for the inside loop lie entirely within the outside loop.
ILLMATOPE, illegal matrix operation
ERROR – The program attempts matrix division. The operation is treated as a MAT multiply, and the compilation continues.
User action: Remove the attempted matrix division. VSI BASIC does not support this operation.
ILLMCHPDP, illegal passing mechanism on PDP–11s
INFORMATION – This error is reported only when the /FLAG=BP2COMPATIBILITY qualifier is in effect. A parameter list contains a BY clause that is invalid in PDP–11 BASIC-PLUS-2, for example, specifying BY DESC for parameters that are not entire arrays or strings.
User action: See the VSI BASIC Reference Manual for allowable BASIC-PLUS-2 parameter-passing mechanisms.
ILLMIDLEN, illegal MID assignment length
ERROR – The value of the length in the MID statement is either greater than the length of the string or less than or equal to zero.
User action: Correct the length to be between 1 and the length of the string.
ILLMIDSTRT, illegal MID starting value
ERROR – The starting value in the MID statement is less than or equal to zero.
User action: Correct the starting value to be greater than or equal to one.
ILLMODMIX, illegal mode mixing
ERROR – The program contains string and numeric operands in the same operation.
User action: Change the expression so that it contains either string or numeric operands, but not both.
ILLMULDEF, illegal multiple definition of name
<name>
More than one variable
A variable and a MAP
A variable and a COMMON
A MAP and COMMON
User action: Use unique names for variables, COMMONs, and MAPs.
ILLMULOPT, OPTIONAL cannot be specified more than once
ERROR – The OPTIONAL clause was specified more than once in the EXTERNAL statement for a single SUB or FUNCTION. This is not allowed because OPTIONAL implies that all parameters following it are optional.
User action: Fix the EXTERNAL statement so that it has at most one OPTIONAL clause per SUB or FUNCTION.
ILLNESDEF, illegally nested DEFs
ERROR – The program contains a DEF function block within another DEF function block.
User action: Remove the inner DEF block. A DEF cannot contain another DEF.
ILLOPEARG, illegal operation for argument
ERROR – The program performs an operation that is inconsistent with the data type of the arguments, for example, an arithmetic operation on variables of the RFA data type.
User action: Remove the operation or change the data type of the arguments.
ILLOPTBAS, illegal OPTION BASE value
INFORMATION – A program compiled with the /ANSI_STANDARD qualifier contains an OPTION BASE statement that specifies a value other than 0 or 1.
User action: Change the OPTION BASE statement to specify either 0 or 1.
ILLQUACOM, illegal qualifier combination
ERROR – In the VAX BASIC Environment, you specified an illegal combination of qualifiers, such as COMPILE/NOSHOW=CDD.
User action: Issue the command again, using a valid combination of qualifiers.
ILLSTROPE, illegal string operator
ERROR – The program specifies an invalid string operation, for example, A$ = B$ – C$.
User action: Replace the invalid operator.
ILLUSAFIE, illegal usage of FIELDed variable
ERROR – A MAT statement operates on an element of a string array that appears in a FIELD statement.
User action: Remove the array from the MAT statement.
ILLUSEUNA, illegal use of unary operator
ERROR – A compiler directive contains an invalid lexical expression, for example, %IF 1 NOT 2.
User action: Correct the invalid lexical expression.
ILLWAIVAL, WAIT value must be in the range 0 to 255, inclusive
ERROR – An integer expression was specified on a WAIT clause that is less than 0 or greater than 255.
User action: Specify an integer expression from 0 to 255.
IMMMODOPE, immediate mode operation requires storage allocation
ERROR – An immediate mode statement attempted to allocate storage, for example, to create a new variable.
User action: None. You cannot create new storage in immediate mode.
IMMNOTANS, immediate mode not valid when ANSI
ERROR – An immediate mode statement was typed when in ANSI mode.
User action: None.
IMPCNTNOT, implied continuation not allowed
ERROR – The program contains an implied continuation line after a statement that does not allow implicit continuation, for example, a DATA statement.
User action: Use an ampersand ( &) to continue the statement.
IMPDECILL, implicit declaration of
<name>
illegal in immediate
mode
ERROR – A new variable was named in an immediate mode statement after a STOP, for example, PRINT B after a STOP in a program that has no variable named B.
User action: None. You cannot create new variables in immediate mode after a STOP statement.
IMPDECNOT implied declaration not allowed for
<name>
with /EXPLICIT
ERROR – A program compiled with the /TYPE=EXPLICIT qualifier contains an implicitly declared variable.
User action: Declare the variable explicitly or compile the program without the /TYPE=EXPLICIT qualifier.
INACODFOL, inaccessible code follows line
<n>
statement
<m>
WARNING – The compiler has detected code that will never be executed, for example, a multistatement line whose first statement is a GOTO, EXIT, ITERATE, RESUME, or RETURN. (VAX BASIC only)
User action: Review the program to determine if the code should be executed. If you determine the code should be executed, then you should revise the program flow logic accordingly. Otherwise, the code is unnecessary and you may want to remove it. In the case of the GOTO, EXIT, ITERATE, RESUME, or RETURN statements, make sure that these statements are the only statements on the line, or the last statement on a multistatement line.
INCDIRSYN, INCLUDE directive syntax error
ERROR – A %INCLUDE directive either is not followed by a quoted string or incorrectly uses the %FROM %CDD or %FROM %LIBRARY clause.
User action: Supply either a quoted string or the correct syntax for the %FROM %CDD or %FROM %LIBRARY clause.
INCFUNUSA, inconsistent function usage for function
<name>
ERROR – The parameter list in a DEF function invocation contains a string where the function expected a number, or vice versa. This message is issued only when the invocation occurs before the DEF statement in the program.
User action: Supply a correct parameter in the function invocation or correct the parameter list in the DEF.
INCRMSERR, INCLUDE directive RMS error number
<number>
ERROR – A %INCLUDE directive caused an RMS error when accessing the specified file.
User action: Take action based on the reported RMS error number.
INCSUBUSE, inconsistent subscript use for
<array-name>
ERROR – The number of subscripts in an array reference does not match the number of subscripts specified when the array was created.
User action: Specify the same number of subscripts.
INIOUTRAN, initial value must be within the specified range
ERROR – The specified initial value is not within the range specified in the RANGE clause.
User action: Change either the initial value or the range values so that the initial value falls within the range.
INPPROMUS, input prompt must be a string constant
ERROR – An INPUT, LINPUT, or INPUT LINE statement list contains a numeric constant immediately following the statement.
User action: Remove the numeric constant. You can specify only a string constant immediately after an INPUT, LINPUT, or INPUT LINE statement.
INSERTB, assuming <keyword>
before
<keyword>
ERROR – The program contains a syntax error. VSI BASIC assumes a keyword is missing and continues compilation under that assumption so that other errors can be detected. The actual program line remains unchanged and no object file is produced.
User action: Examine the line carefully to discover the error. Change the program line to correct the syntax error.
INSERTM, assuming <keyword>
to match
<keyword>
ERROR – The program contains a syntax error. VSI BASIC assumes a keyword is misspelled and continues compilation under that assumption so that other errors can be detected. The actual program line remains unchanged and no object file is produced.
User action: Examine the line carefully to discover the error. Change the program line to correct the syntax error.
INSSPADYN, insufficient space for MAP DYNAMIC variable in MAP
<name>
ERROR – A variable named in a MAP DYNAMIC statement is larger than the MAP, for example, a GFLOAT variable in a MAP that is only four bytes long.
User action: Increase the size of the MAP so that it is large enough to hold the largest member.
INTCODERR, an internal coding error has been detected. Submit an SPR.
ERROR – An error has been detected in the VSI BASIC compiler.
User action: Please submit a software problem report (SPR) with the source code of a small program that produces this error.
INTCONEXC, integer constant exceeds machine integer size
ERROR – The value specified in a DECLARE CONSTANT statement exceeds the largest allowable value for an integer.
User action: Supply a value in the valid range.
INTCONREQ, integer constant required
DIM A ('123'D)
User action: Supply an integer constant.
INTDATTYP, integer data type not supported in ANSI
ERROR – A program compiled with the /ANSI_STANDARD qualifier contains an integer variable or array.
User action: Remove the integer variable or array.
INTERR, integer error or overflow
WARNING – The program contains an integer expression whose value is outside the valid range.
User action: Modify the expression so that its value is within the allowable range or use an integer data type that can contain all possible values for the expression.
INTERRDES, please submit an SPR ---- internal error in comment processing
WARNING – An error has been detected while processing a comment in the VSI BASIC compiler.
User action: Please submit a software problem report (SPR) with the source code of a small program that produces the error.
INTERRSCA, please submit an SPR ---- internal error in SCA support
ERROR – An error has been detected in the SCA support in the VSI BASIC compiler. If you recompile your program without the /ANALYSIS_DATA qualifier, this error should no longer appear.
User action: Please submit a software problem report (SPR) with the source code of a small program that produces the error.
INVCHNNUM, invalid channel number, must be greater than zero
ERROR – A channel number less than or equal to zero was specified.
User action: Change the channel number to be greater than zero.
INVCONREQ, invalid conversion requested
ERROR – The program contains a reference to the REAL or INTEGER functions and the argument is an entire array, GROUP, RECORD, or RFA expression.
User action: Remove the invalid argument. The argument to these functions must be a numeric expression.
INVINTTYP, invalid integer type
ERROR – A reference to the INTEGER function contains an invalid data-type keyword, for example, A = INTEGER(A, SINGLE).
User action: Change the invalid data-type keyword. The INTEGER function returns only BYTE, WORD, LONG, or QUAD values.
INVLOGNAM, invalid logical name
ERROR – The argument to the ASSIGN compiler command specified a logical name length of less than 1 or greater than 63.
User action: Supply a valid logical name.
INVPRISPE, invalid priority specification, expecting < or >
ERROR – On the SET INPUT PRIORITY statement, you specified a character other than < or > to indicate the relative priorities of the two transformation numbers.
User action: Specify the priority relationship with less than < (lower priority) or greater than > (higher priority).
INVREATYP, invalid real type
ERROR – A reference to the REAL function contains an invalid data-type keyword, for example, A = REAL(A, LONG).
User action: Change the invalid data-type keyword. The REAL function returns only SINGLE, DOUBLE, GFLOAT, SFLOAT, TFLOAT, XFLOAT, or HFLOAT values.
INVSUBTYP, <data-type>
is not a subtype
of <data-type>
ERROR – The program contains an invalid declaration containing contradictory type declarations, for example, DECLARE REAL BYTE.
User action: Supply a valid declaration. Use only valid integer subtypes for INTEGER and only valid floating-point subtypes for REAL.
IS_NOTDYN, <name>
is not a DYNAMIC MAP
variable of MAP <name>
ERROR – A REMAP statement names a variable that was not named in the MAP DYNAMIC statement for that MAP.
User action: Remove the variable from the REMAP statement or name the variable in the MAP DYNAMIC statement for that map.
ITEMUSAPP, ITERATE must appear within a loop
ERROR – The program contains an ITERATE statement that is not within a FOR-NEXT, WHILE, or UNTIL loop.
User action: Remove the ITERATE statement, or surround it with a loop.
JMPBADBLO, jump to line number <line
number>
is into a controlled block
ERROR – The program attempts to transfer control to a WHEN block or associated handler.
User action: Change the program logic so that it does not transfer control to a WHEN block or associated handler.
JMPBADLAB, jump to label: <label>
is
into a block
ERROR – The program attempted to transfer control into a FOR-NEXT, WHILE, UNTIL, IF, or SELECT-CASE block.
User action: Change the program logic so that it does not transfer control into a block.
JMPBADLIN, jump to line number <number>
is into a block
INFORMATION – The program transfers control to a line number within a FOR-NEXT, WHILE, UNTIL, IF, or SELECT-CASE block.
User action: This is an informational message. However, it is bad programming practice to transfer control into a block.
JMPINTDEF, jump into DEF
ERROR – The program attempts to transfer control into a DEF block.
User action: Change the control statement; you cannot transfer control into a DEF block except by invoking the function.
JMPOUTDEF, jump out of DEF
ERROR – The program attempts to transfer control out of a DEF block.
User action: Change the control statement. Use an EXIT DEF, FNEXIT, FNEND, or END DEF statement to transfer control out of a DEF block.
JMPOUTHAN, jump out of HANDLER
ERROR – The program attempts to transfer control out of an error handler.
User action: Change the control statement. Use an EXIT HANDLER, RETRY, or CONTINUE statement to transfer control out of an error handler.
JMPOUTPRO, jump out of program unit
ERROR – In a source file containing more than one program module, a statement attempts to transfer control from one module into another.
User action: Change the statement that attempts to transfer control; you cannot transfer control into a different program module.
JMPUNRLIN, jump to unreferenceable line number
<number>
ERROR – A RESUME, GOSUB, or GOTO statement attempts to transfer control to a CASE statement.
User action: Label or number the SELECT statement and transfer control to the beginning of the SELECT-CASE block.
KEYCANNOT, key <name>
in MAP
<map-name>
cannot be a dynamic variable
ERROR – A KEY clause in an OPEN statement specifies a variable declared as dynamic in a MAP DYNAMIC statement.
User action: Specify a static variable in the KEY clause; that is, declare the variable in a MAP statement, not a MAP DYNAMIC statement.
KEYIS_NEE, key is needed for indexed files
ERROR – The program attempts to open an indexed file for output, and the PRIMARY KEY clause is missing.
User action: Supply a PRIMARY KEY clause.
KEYMUSBE, key must be either word, longword, quadword, string, decimal, record or group
ERROR – A FIND or GET statement on an indexed file contains a key specification that is not a WORD, LONG, QUAD, STRING, DECIMAL, or an 8-byte RECORD or GROUP expression.
User action: Change the key specification to be a WORD, LONG, QUAD, STRING, DECIMAL, or an 8-byte RECORD or GROUP expression.
KEYMUSTBE, key, <vbl-name>
in map
<map-name>
must be either word,
longword, quadword, string, decimal, record or group
ERROR – An OPEN statement contains a key specification that is not an unsubscripted WORD, LONG, QUAD, STRING, DECIMAL, or an 8-byte RECORD or GROUP variable.
User action: Change the key specification to be an unsubscripted WORD, LONG, QUAD, STRING, DECIMAL, or an 8-byte RECORD or GROUP variable.
KEYNOTMAP, KEY <vbl-name>
is not an
unsubscripted variable in MAP
<name>
ERROR – An indexed file OPEN statement specifies a KEY variable that does not appear in a MAP statement.
User action: Place the KEY variable in the MAP referenced by the OPEN statement's MAP clause.
KEYREQMAP, KEY clauses require a MAP clause
ERROR – An OPEN statement specifies KEY clauses without specifying a MAP clause.
User action: Supply a MAP clause to define the position of the keys in the record buffer.
KEYSEGMUS, key segment <name>
in map
<map-name>
must be a string
key
OPEN "INDEX.DAT" AS FILE #1, ORGANIZATION INDEXED, & PRIMARY KEY (A$, B$, C%), MAP ABC
User action: Specify only string variables in segmented keys.
KEYSINC, <keyword>
keyword inconsistent
with <keyword>
ERROR – An OPEN statement contains contradictory record format specifications, for example, both FIXED and VARIABLE.
User action: Specify only one record format.
KEYTOOLON, KEY <name>
in MAP
<name>
is too long (max is 255)
ERROR – A KEY variable is longer than 255 characters.
User action: Reduce the length of the KEY variable. The maximum key length is 255 characters.
KEYWORINC, keyword inconsistent with <OPEN
clause>
clause
ERROR – An OPEN statement contains an ALLOW, ACCESS, or RECORDTYPE clause whose keyword argument is invalid, for example, ACCESS FORTRAN.
User action: Change the clause argument to a valid keyword for that clause.
LABNOTDEF, label <label>
not
defined
ERROR – The program tries to transfer control to a nonexistent label.
User action: Define the label before transferring control to it.
LABNOTLAB, label <name>
does not label
an active block statement
ERROR – An EXIT statement in a loop, if-then-else, or SELECT-CASE block specifies a label that does not refer to that block.
User action: Change the program so that the label actually refers to the block in which the EXIT statement occurs.
LABNOTLOO, label <name>
does not label
an active loop statement
ERROR – In a loop, an EXIT or ITERATE statement specifies a label that does not refer to that loop.
User action: Change the program so that the label actually refers to the loop in which the EXIT or ITERATE statement occurs.
LANFEADEC, language feature is declining
INFORMATION – The program contains a language feature that is not recommended for new program development, for example, the FIELD statement. This error is reported only when the /FLAG=DECLINING qualifier is in effect.
User action: Use: 1) MAP, MAP DYNAMIC and REMAP statements instead of FIELD, 2) EDIT$ rather than CVT$$, and 3) overlaid MAPs rather than CVTxx functions.
LANFEAINC, language feature incompatible with BASIC-PLUS-2
INFORMATION – The program contains syntax that results in different behavior under VSI BASIC and PDP–11 BASIC-PLUS-2, for example, opening a terminal–format file. This error is reported only when the /FLAG=BP2COMPATIBILITY qualifier is in effect.
User action: None.
LANFEAINH, language feature inhibits optimization
INFORMATION – A program compiled with the /NOSETUP qualifier contains a language feature that requires /SETUP, for example, the RESUME statement. The compilation continues with /SETUP in effect.
User action: None. The program must be compiled with /SETUP in effect for the language feature to work.
LANFEANOT, language feature not available in BASIC-PLUS-2
INFORMATION – The program contains a language element that is not supported in BASIC-PLUS-2, for example, RECORD statements. This error is reported only when the /FLAG=BP2COMPATIBILITY qualifier is in effect.
User action: If the program must run under both VSI BASIC and PDP–11 BASIC-PLUS-2, you must remove the incompatible language feature.
LANFEAOPE, language feature not available in BASIC
ERROR – The program contains a PRINT statement with a RECORD clause. BASIC does not support the RECORD clause in PRINT statements.
User action: Remove the RECORD clause.
LEFBOUSPE, left boundary must be less than the right boundary
ERROR – In a statement that specifies a viewport or windowsize, you specified a left boundary that is greater than or equal to the corresponding right boundary.
User action: Correct the left boundary so that it is less than the right boundary.
LENDYNSTR, string length not allowed on dynamic string
<name>
ERROR – The program contains a dynamic string variable declaration that specifies a string length.
User action: Length specifications are allowed only for fixed-length strings; remove the length specification from the dynamic string, or allocate the string in a MAP or COMMON.
LENNUMFIL, string length not allowed on numeric FILL
ERROR – The program contains a numeric FILL item that specifies a length.
User action: Remove the length specification from the numeric FILL item.
LETDIRSYN, LET directive syntax error
ERROR – A %LET directive contains a syntax error, for example, an invalid lexical identifier.
User action: Use the correct syntax for the %LET directive.
LETKEYREQ, LET keyword required in ANSI
INFORMATION – A program compiled with the /ANSI_STANDARD qualifier contains an assignment statement that omits the LET keyword.
User action: Supply a LET keyword.
LEXDIRSYN, lexical directive syntax error
ERROR – A syntax error was detected in a lexical directive.
User action: Correct the syntax of the lexical directive.
LEXIDEMUS, lexical identifier must be declared before reference
ERROR – You reference a lexical identifier before you declare it.
User action: Declare the lexical identifier before you reference it.
LINNOTALL, line numbers not allowed, use the EDIT command
ERROR – An EDIT command with a line number has been found in a program without line numbers.
User action: Use the EDIT command without specifying a line number to invoke a text editor.
LINNUMERR, illegal line number
ERROR – The program contains a line number that is outside the valid range or is not a valid integer (note that the percent sign (%) suffix is not valid for line numbers).
User action: Specify only integer line numbers in the range 1 to 32,767, inclusive.
LINNUMINC, line number may not appear in INCLUDE directive file
ERROR – The file specified in a %INCLUDE compiler directive contains a line number.
User action: Remove the line number from the file.
LINNUMUND, line number <n>
undefined due
to conditional compilation
ERROR – The program references a line number that does not appear in the object code as a result of the branch taken in a %IF-%THEN-%ELSE-%END-%IF directive.
User action: Change the %IF-%THEN-%ELSE-%END-%IF directive or remove the line number reference.
LINOUTORDE, Line numbers are out of order
ERROR – The line numbers in an Alpha BASIC program are not in ascending order.
User action: Reorder the line numbers and/or statements in your program so that the line numbers are in ascending order.
LINREQTWO, LINES output requires at least 2 X,Y points
ERROR – A LINE graphic output statement specifies less than 2 points.
User action: Specify a minimum of 2 points in the LINE graphic output statement.
LNPNOTBP2, programs without line numbers are not allowed in BASIC-PLUS-2
INFORMATION – BASIC-PLUS-2 does not support programs without line numbers. This error is reported only when the /FLAG = BP2COMPATIBILITY qualifier is in effect.
User action: Add a line number to the first line of the program.
LOGOPENON, logical operation on noninteger quantity
ERROR – The program contains a logical operation performed on strings or real numbers.
User action: Change the logical operands to integers.
LOOINDMUS, loop control variable must be a numeric variable
ERROR – A FOR statement specifies a string variable as the loop control variable.
User action: Specify a numeric variable. You can use only numeric variables as loop control variables.
LOOINIMUS, loop initial value must be a numeric expression
ERROR – A FOR statement attempts to assign a string expression as the loop control variable's initial value.
User action: Remove the string expression. You can assign only numeric values as the loop's initial value.
LOOLIMMUS, loop limit must be numeric
ERROR – A FOR statement attempts to assign a string expression as the loop control variable's limiting value.
User action: Remove the string expression. You can assign only numeric values as the loop control variable's limiting value.
LOOWILNEV, loop will never execute
WARNING – The program contains a FOR/NEXT loop that is not executable, for example, FOR I% = 1% TO 0%. Compilation continues, but the loop is ignored.
User action: Change the loop parameters or insert an appropriate STEP clause.
LOWLSSUP, lower bound must be less than upper bound
ERROR – The lower bound specified in the array is greater than the upper bound.
User action: Correct the bounds.
LOWNOTVIR, lower bound not permitted with virtual arrays
ERROR – Lower bounds of virtual arrays must be zero.
User action: Correct the lower bounds to be zero.
LOWNOTZERO, lower bound must be zero
ERROR – The lower bound of the array must be zero.
User action: Correct the lower bound to be zero.
LOWRANVAL, range lower value must be less than upper value
ERROR – In the RANGE clause, the first value is greater than the second value.
User action: Change the range clause so that the first value is less than the second value.
LRSETNOT, <keyword>
is not allowed with
MID
ERROR – The LSET and RSET keywords are not allowed with MID.
User action: Change the LSET or RSET keyword to LET.
MACNOTDEF, macro is not defined
ERROR – The macro identifier used in this %UNDEFINE directive was not previously defined by a %DEFINE directive.
User action: Verify that the identifier has been previously defined with the %DEFINE directive. Verify that the %DEFINE and %UNDEFINE macro IDs match.
MAPDYNNOT, MAP DYNAMIC <map-name>
may
not be larger than 32,767 bytes
ERROR – A MAP DYNAMIC statement references a map that is greater than 32,767 bytes in size.
User action: Reduce the size of the map, as defined in the MAP statement, or MAP statements, to 32,767 bytes or less.
MAPDYNREQ, MAP DYNAMIC <name>
requires
corresponding static MAP
ERROR – The program contains a MAP DYNAMIC statement whose MAP name does not appear in a MAP statement.
User action: Provide a MAP with the same name as the MAP DYNAMIC name.
MAPNOTDEF, MAP <name>
used in OPEN not
defined
ERROR – An OPEN statement's MAP clause references a nonexistent MAP.
User action: Define the MAP referenced by the MAP clause, or remove the MAP clause.
MAPTOOLAR, MAP too large in OPEN
FATAL – The size of the MAP referenced in an OPEN statement is greater than 32,767 bytes.
User action: Reduce the size of the MAP.
MAPVARALI, variable <name>
not aligned
in multiple references in MAP
<name>
ERROR – More than one overlaid MAP contains the same variable, but the variable's position differs in the MAPs.
User action: The same variable can appear in multiple overlaid MAPs, but the variable must occupy the same position in the PSECT; make sure that the variable appears in the same position in the MAPs.
MAPVARREF, MAP variable <name>
referenced before declaration
INFORMATION – A reference to a MAP variable occurs before the MAP statement.
User action: Make sure that the MAP statement precedes any references to variables in the MAP.
MATDIMERR, matrix dimension error
Contains a MAT IDN, MAT TRN, or MAT INV performed on a one-dimensional array
Performs a matrix operation that requires identical subscripts in the operand arrays and those arrays have different subscripts
User action: Dimension the arrays to the proper number of subscripts.
MATLOWBOU, matrix must have lower bound 0 and upper bound 4
ERROR – The specified transformation matrix either has a lower bound other than 0 or an upper bound other than 4.
User action: Declare the matrix such that both dimensions have a lower bound of 0 and an upper bound of 4.
MATMUL2OP, MAT multiply of 2 4X4 matrices required
ERROR – You specified the wrong dimensions in a matrix in the MAT multiply statement or a WITH clause on the DRAW statement, or you specified a nonmultiplication operation in a multiple operation MAT arithmetic statement. For example: MAT A=B*C+D. A two-dimensional matrix with lower bounds 0 and upper bounds 4 in both dimensions is required.
User action: Declare the matrix to be a two-dimensional matrix with lower bounds 0 and upper bounds 4 in both dimensions.
MATONEOR2, MAT statements require one or two dimensions
ERROR – A MAT statement references an array of more than two dimensions.
User action: Remove the array reference. MAT statements are valid only on arrays of one or two dimensions.
MAXCONCOM, maximum conditional compilation depth exceeded
FATAL – Too many nested %IF-%THEN-%ELSE-%END-%IF directives are contained in the program.
User action: Reduce the number of nested %IF-%THEN-%ELSE-%END-%IF directives. You can nest up to eight such constructs.
MAXDIMEXC, maximum number of dimensions exceeded. Maximum is 32
ERROR – An array declaration specifies more than the allowed number of dimensions.
User action: Reduce the number of dimensions to 32 or less.
MAXKEYSEG, maximum of 8 key segments exceeded
ERROR – An OPEN statement specifies a segmented key with more than eight segments.
User action: Reduce the number of segments in the KEY clause to eight or less.
MAXPAREXC, maximum parameters exceeded for
<name>
. Maximum is
<number>
ERROR – The program attempts to declare a DEF with more than eight parameters or a subprogram with more than 255 parameters.
User action: Reduce the number of parameters; DEFs allow up to eight parameters and subprograms allow up to 255 parameters.
MAXPAREXP, no more than <number>
parameter(s) expected for
<sub--func--name>
ERROR – An external SUB or FUNCTION was called with more parameters than were specified in the EXTERNAL statement, including both OPTIONAL and non-OPTIONAL parameters.
User action: Reduce the number of parameters in the call.
MERGE, merged <item>
and
<item>
ERROR – The program contains a syntax error. VSI BASIC assumes that there is an incorrect space, for example, PR INT. Compilation continues so that other errors can be detected. The actual program line remains unchanged and no object file is produced.
User action: Examine the line carefully to discover the error. Change the program line to correct the syntax error.
MINPAREXP, at least <number>
parameter(s) expected for
<sub--func--name>
ERROR – An external SUB or FUNCTION was called with fewer parameters than were specified as non-OPTIONAL parameters in the EXTERNAL statement.
User action: Increase the number of parameters in the call so that the number of parameters is equal to or greater than the number of non-OPTIONAL parameters.
MISENDIF, missing END IF directive before end of program unit
ERROR – A %IF directive crosses a program module boundary.
User action: Terminate the %IF with a %END %IF before beginning a new source module.
MISENDFOR, missing END <block>
for
<block>
at line
<n>
statement
<m>
ERROR – The program contains a SELECT, IF, or DEF without a matching END statement.
User action: Supply a matching END statement.
MISMATEND, mismatched END, expected
<block>
ERROR – The program contains an incorrect END statement, for example, an END RECORD statement instead of an END GROUP statement.
User action: Supply the correct type of END statement.
MISMATFOR, missing NEXT for <item>
at
line <n>
statement
<m>
ERROR – The program contains a FOR, WHILE, or UNTIL without a matching NEXT.
User action: Supply the matching NEXT statement.
MODNOTFND, module <mod-name>
not found
in text library <text-lib-name>
ERROR – The module name you specified in a %INCLUDE directive was not found in the text library you specified.
User action: Place the module name in the specified text library.
MULCHRARR, multiple character array name not ANSI
INFORMATION – A program compiled with the /ANSI_STANDARD qualifier contains an array whose name contains more than one character.
User action: Reduce the length of the name to a single character.
MULCHRDEF, multiple character DEF name not ANSI
INFORMATION – A program compiled with the /ANSI_STANDARD qualifier contains a DEF whose name contains more than one character.
User action: Reduce the length of the name to a single character.
MULDEFLEX, multiple definition of lexical identifier is illegal
ERROR – A lexical constant is named in more than one %LET directive.
User action: Declare the lexical constant only once with %LET.
MULHANSPE, multiple handlers specified for WHEN block
ERROR – A WHEN block specifies both an attached and detached error handler.
User action: Change the WHEN block to specify either an attached or detached error handler.
MULMAIPROG, multiple main program units are illegal
ERROR – More than one main program unit has been detected in a single source file.
User action: Modify your source file so that all VSI BASIC statements are contained within a single main program or within a subprogram.
MULNOTBP2, multiple program units per module not BASIC-PLUS-2 compatible
INFORMATION – A program compiled with the /FLAG=BP2COMPATIBILITY qualifier contains more than one program unit. BASIC-PLUS-2 does not allow more than one program unit in a single file.
User action: Separate the program into individual program units and compile the units separately.
MULOPTBAS, multiple OPTION BASE statements not ANSI
ERROR – A program compiled with the /ANSI_STANDARD qualifier contains more than one OPTION BASE statement.
User action: Specify the OPTION BASE statement only once per program.
MULPRONOT, multiple program units per module not ANSI
INFORMATION – A program compiled with the /ANSI_STANDARD qualifier contains more than one program unit.
User action: Rewrite the program converting the subprograms to subroutines.
MULSTAPER, multiple statements per line not ANSI
INFORMATION – A program compiled with the /ANSI_STANDARD qualifier contains more than one statement on a line.
User action: Change the program so that each statement has its own line number.
MULTDEF, multiple definition of
<name>
WARNING – A variable is declared in more than one declarative statement.
User action: Make sure that the variable is declared only once.
NAMNOTREC, name <name>
is not of a
RECORD component
ERROR – A RECORD component reference uses an invalid record name, for example, A::B when A is not a RECORD name.
User action: Change the erroneous reference.
NAMTOOLON, name is too long, changed to
<name>
WARNING – A variable or array name is longer than 31 characters. VSI BASIC truncates the name to 31 characters and continues compilation so that other errors can be detected. The actual program line remains unchanged and no object file is produced.
User action: Reduce the length of the variable name to 31 or fewer characters.
NEGFILSTR, negative FILL or string length
ERROR – The program contains a negative FILL specification or string length.
User action: Change the FILL specification or string length to a positive number.
NESFORLOO, nested FOR loops with same control variable
<name>
ERROR – The program contains nested FOR/NEXT loops that use the same index variable.
User action: Change the index variable for all but one of the loops.
NOBASFRAM, no BASIC frame on stack
ERROR – VSI BASIC could not find a valid stack frame. This could be caused by running a program with /CHECK=NOBOUNDS or by a non-BASIC subprogram.
User action: Debug the program before running with /CHECK=NOBOUNDS or check the logic of the non-BASIC subprogram.
NODESCALL, no descriptor allocated for array
<name>
ERROR – An immediate mode statement required an array descriptor, but it was not available. VSI BASIC allocates array descriptors only if the program code requires it.
User action: None.
NODIAGFILE, unsaved changes, no diagnostics file produced
WARNING – The program in memory contains changes that have not been saved; therefore, no diagnostics file will be produced from this compilation.
User action: SAVE or REPLACE the file.
NOEDIT, no change made
WARNING – The search string in an EDIT command was not located in the text.
User action: Enter valid search string.
NOFILEALL, a file specification is not allowed with the REPLACE command
ERROR – The REPLACE command does not allow the use of a file specification.
User action: Use either the SAVE command with a file specification or the REPLACE command without one.
NOFRAME, compiled procedure is currently not active
WARNING – A program containing multiple compilation units has been stopped while running in the environment due to a STOP statement or a Ctrl/C entered by the user. The NOFRAME error indicates that the routine executing when the program stopped is not the last compilation unit in the source file. You can examine or modify a variable in immediate mode only if the current routine is the last compilation unit in the source file.
User action: If you do not intend to debug your program in immediate mode, no action is required. If you do intend to debug your program in immediate mode, make the routine that you want to debug the last compilation unit in the source file. The symbols for the last compilation unit are always available. Alternatively, use the OpenVMS Debugger to debug your program.
NOHANSPE, no handler specified for WHEN block
ERROR – A WHEN block has been found that does not specify an error handler.
User action: Specify an error handler for the WHEN block.
NOLINENUM, missing line number on first line
WARNING – There is no line number on the first line of the program.
User action: Add a line number to the first line of the program or remove all line numbers from the program.
NOLNROOM, out of memory for line numbers
ERROR – The program contains more line-numbered statements than VSI BASIC allows.
User action: Change the program so that it uses multistatement lines instead of having each statement on its own line or split the program into one or more program units in separate files.
NOMAPNAME, MAP statement requires map name
ERROR – A MAP statement does not specify a map name.
User action: Specify a name for the MAP.
NOSCAFILE, unsaved changes, no analysis file produced
WARNING – The program in memory contains changes that have not been saved; therefore, no data analysis file will be produced from this compilation.
User action: SAVE or REPLACE the file.
NOSRCLINE, unsaved changes, no source line debugging available
WARNING – The program in memory contains changes that have not been saved; therefore, no source line debugging will be available from this compilation.
User action: SAVE or REPLACE the file.
NOSUCHMAP, no such MAP area
<name>
ERROR – A REMAP statement names a nonexistent MAP area.
User action: Supply a MAP before executing the REMAP statement.
NOTIMP, not implemented in this version
ERROR – The program attempted to use a feature that does not exist in this version of VSI BASIC.
User action: Examine your program and remove the nonimplemented feature.
NOTMACROOM, out of memory for macro definitions
ERROR – The limit on the number of macro definitions has been exceeded.
User action: Reduce the number of %DEFINE definitions, or undefine some previously defined macros with the %UNDEFINE directive.
NOTPASSBY, <item>
may not be passed BY
<mechanism>
ERROR – The program specifies an incorrect passing mechanism for a parameter's data type, or an invalid parameter. For example, you cannot pass an entire array BY VALUE, nor can you pass a label as a parameter.
User action: Specify a valid parameter or passing mechanism.
NOTRANS, no main program
WARNING – When a RUN command was typed, only subroutines or functions were available. VSI BASIC requires a main program to receive the transfer of control.
User action: Supply a main program.
NOTRECVBY, <item>
may not be received
by <mechanism>
ERROR – A subprogram specifies an invalid parameter or an incorrect passing mechanism for a parameter's data type. For example, you cannot receive an entire array BY VALUE.
User action: Specify a valid parameter or passing mechanism.
NOTXTROOM, out of memory for statement text
ERROR – The program contains more text than VSI BASIC allows.
User action: Split the program into one or more program units.
NOVALUE, <text>
keyword requires a
value
ERROR – A keyword command was typed without a value.
User action: Supply a valid keyword value.
NUMARREXP, numeric array expected
ERROR – A CHANGE statement does not specify a numeric array.
User action: Supply a numeric array in the CHANGE statement.
NUMCONREQ, numeric constant required
DECLARE INTEGER CONTANT A = "ABC"
User action: Supply a numeric constant.
NUMIS_NEE, numeric expression is required
ERROR – The program contains a string expression in a context that requires a numeric expression, for example, WHILE A$.
User action: Supply a numeric expression.
NUMVARREQ, numeric variable required
ERROR – A nonnumeric variable was found with a numeric data type.
User action: Specify a numeric variable.
OBJFAIL, failure in loading object file
FATAL – In the VAX BASIC Environment, either an attempt was made to load a non-BASIC object module, or the compiler could not find the object file referenced by a CALL statement or EXTERNAL FUNCTION reference.
User action: If the object file resides in the Common Run-Time Library, you must link the program at DCL level. If the object file is in a user-supplied library, use the DCL LIBRARY command to install the missing object module. You can load only VSI BASIC for OpenVMS object modules.
ONENOTWHE, ON ERROR not allowed in WHEN block or handler
ERROR – An ON ERROR statement has been found in a WHEN block or an associated error handler.
User action: Remove the ON ERROR statement from the WHEN block or associated error handler.
OPEEXPNOT, operator expected, not found
ERROR – A compiler directive contains an invalid lexical expression that has a right parenthesis immediately followed by a lexical identifier.
User action: Correct the lexical expression.
OPEMUSFOL, operator must follow right parenthesis
ERROR – The program contains an incorrect lexical expression.
User action: Correct the lexical expression.
OPENIN, error opening <file-name>
as
input
ERROR – An error was detected in attempting to open a file for input.
User action: Make sure the file specification is correct.
OPENOUT, error opening <file-name>
as
output
ERROR – An error was detected in attempting to open a file for output.
User action: Supply a valid file specification, or take corrective action based on the associated message.
OPNCLAVAL, OPEN clause <clause>
value
greater than <number>
ERROR – An OPEN statement contains a RECORDSIZE, FILESIZE, EXTENDSIZE, WINDOWSIZE, BLOCKSIZE, BUCKETSIZE, or BUFFER clause whose argument is too large.
User action: Supply a smaller value for the argument.
OPNDUPCLA, duplicate OPEN clause
WARNING – An OPEN statement contains more than one clause of the same type.
User action: Remove one of the clauses.
OPNILLCLA, <clause>
is an unsupported
OPEN clause
ERROR – An OPEN statement specifies invalid attributes for the file, for example, CLUSTERSIZE on OpenVMS systems, or uses the keyword COMMON in an I/O clause.
User action: Substitute valid attributes for the file or remove the COMMON keyword.
OPNINCCLA, <keyword>
keyword is
inconsistent with file organization
ERROR – An OPEN statement contains a clause that is not appropriate for the specified file organization, for example, opening a relative file with the ACCESS APPEND clause.
User action: Remove the inconsistent clause.
OPTBASMUS, OPTION BASE must be before array declarations
ERROR – A program compiled with the /ANSI_STANDARD qualifier contains an OPTION BASE statement that lexically follows an array declaration.
User action: Move the OPTION BASE statement so that it lexically precedes the array declaration.
OPTCLACON, OPTION clause occurs more than once
ERROR – The OPTION statement contains a duplicate clause, for example, specifying the default integer size as both BYTE and LONG.
User action: Remove one of the clauses.
OPTNOTALL, OPTIONAL not allowed on EXTERNAL PICTURE
ERROR – An attempt was made to specify the OPTIONAL keyword on an EXTERNAL PICTURE declaration. This is not allowed because OPTIONAL parameters should be used for calling non-BASIC procedures only.
User action: Remove the OPTIONAL keyword from the EXTERNAL PICTURE declaration.
OPTOUTSEQ, OPTION statement out of sequence
ERROR – The OPTION statement is either: 1) not the first statement in a main program, or 2) not the first statement following the SUB or FUNCTION statement.
User action: Move the OPTION statement so that it is either the first statement in the main program or the first statement following the SUB or FUNCTION statement in the subprogram.
ORGUNDREQ, ORGANIZATION UNDEFINED requires FOR INPUT clause
ERROR – The program opens a file with ORGANIZATION UNDEFINED, but does not specify FOR INPUT.
User action: Specify FOR INPUT in the OPEN statement. You cannot create a file with an undefined file organization.
OVFCHKSUP, OVERFLOW checking supported only for INTEGER and DECIMAL
ERROR – Overflow checking was specified for a floating-point data type in: 1) a compiler command, 2) a qualifier to the DCL BASIC command, or 3) an OPTION statement.
User action: Specify overflow checking only for INTEGER or DECIMAL data types or both.
OVRNOLINE, <keyword>
overrides
NOLINE
WARNING – The program: 1) was compiled with /NOLINES and 2) uses a keyword that requires line number information. For example, ERL and RESUME with a line number both require that the program be compiled with /LINES.
User action: None. If you use a keyword that requires line number information, VAX BASIC automatically overrides the /NOLINE qualifier.
PAREXPFOR, <n>
parameters expected for
<routine>
ERROR – The CALL or invocation of a routine specifies a different number of parameters than the number specified when the routine was declared.
User action: Change the number of parameters to match the number declared.
PARINCPRE, parameter <name>
inconsistent
with previous declaration or reference
ERROR – An external subprogram or DEF function declaration specifies a data type for one of the parameters that is different than the data type the SUB, FUNCTION, or DEF statement specifies.
User action: Change the specified data type in either the declaration or the SUB, FUNCTION, or DEF statement so that the data types agree.
PARMODCHA, mode for parameter <n>
of
routine <name>
changed to match
declaration
INFORMATION – The data type specified in a routine invocation does not match that of the routine declaration. VSI BASIC issues this message only if the data-type conversion results in a parameter that cannot be modified by the routine that was invoked.
User action: Make the data-type specifications in the declaration and the invocation match.
PARMODNOT, mode for parameter <n>
of
routine <name>
not as declared
ERROR – The CALL or invocation of a routine specifies a string argument for a parameter that was specified as a numeric when the routine was declared, or vice versa.
User action: Change the string parameter to numeric, or vice versa.
PARNOTENT, parenthesis illegal, entire array required context
ERROR – Parenthesis are used to specify an entire array in a context where an entire array is always required.
User action: Remove the empty parenthesis from the entire array reference.
PARSTRNOT, parameter <n>
of
<type>
structure not as declared
ERROR – The actual parameter list in subprogram CALL or an invocation specifies an entire array where the subprogram declaration specified a simple variable or vice versa.
User action: Change the actual parameter list to match the declared parameter list or vice versa.
PARTYPREQ, parameter type specification required with /EXPLICIT
ERROR – In a program compiled with /TYPE=EXPLICIT, no data-type keyword is specified for a parameter.
User action: Supply a data-type keyword for the parameter. There are no default data types when you compile a program with /TYPE=EXPLICIT.
PASMECDEF, passing mechanism not allowed for DEF
ERROR – A DEF function declaration specifies a passing mechanism for a parameter.
User action: Remove the passing mechanism clause.
PASMECDIS, passing mechanism disagrees with declaration
ERROR – The CALL or invocation of a routine specifies a different passing mechanism for a parameter than that specified when the routine was declared.
User action: Remove the BY clause specified in the CALL or invocation; VSI BASIC automatically passes parameters with the passing mechanism specified when the routine was declared.
PASMECNOT, passing mechanism not allowed for
<item>
ERROR – A program specifies a passing mechanism in a context other than the invocation or declaration of an external subprogram.
User action: Remove the passing mechanism clause.
PASWITNO, <name>
has a passing
mechanism specified with no parameter list
WARNING – A CALL statement, external function reference, or EXTERNAL statement specifies a BY clause but does not specify a formal parameter list.
User action: Remove the BY clause or supply a parameter list.
PATNOTREC, path name does not specify a CDD/Repository record
ERROR – The %INCLUDE directive contains an invalid path name for a record definition.
User action: Supply a valid path name for a record definition.
PICWHINOT, exit from PICTURE while not in PICTURE
ERROR – An EXIT PICTURE statement was found in a module that is not a PICTURE subprogram.
User action: Remove the EXIT PICTURE statement.
PLACENODESIGN, placeholders illegal without /DESIGN=PLACEHOLDERS
ERROR – A placeholder occurred in the source file and the /DESIGN=PLACEHOLDERS option was not specified.
User action: Recompile the program and specify the qualifier.
PLACENODOT, repetition of pseudocode placeholders not allowed
ERROR – A pseudocode placeholder was syntactically incorrect.
User action: You should remove the trailing periods following the pseudocode placeholder.
PLACENOEXE, placeholders detected – source cannot be executed
ERROR – The source code for a RUN command in immediate mode contained at least one placeholder, therefore it could not be executed.
User action: You should remove the placeholders from the source code and reissue the command.
PLACENOOBJ, placeholders detected – no object produced
INFORMATION – The program contained one or more placeholders and therefore no object module was created.
User action: Remove the placeholders from the source code.
PLACEUNMAT, unmatched placeholder delimiter
ERROR– A placeholder was syntactically incorrect because the number of opening and closing brackets did not match.
User action: First, make sure that the placeholder does not span multiple source lines. Second, add or remove brackets until they are appropriately paired.
PLACEWRDOT, invalid placeholder repetition
ERROR – A list placeholder was syntactically incorrect. Three periods were expected.
User action: Add trailing periods until there are three periods following the placeholder.
POIREQONE, POINTS output requires at least 1 X,Y point
ERROR – You do not specify a point in the POINT graphic output statement.
User action: Specify a minimum of 1 point in the POINT graphic output statement.
POSGTRTAR, starting position greater than target length
ERROR – The starting value in the MID statement is greater than the length of the string.
User action: Correct the value to be less than or equal to the length of the string.
PRELOGNAM, previous logical name assignment replaced
INFORMATION – The specified logical name already existed. The new equivalence name replaces the old one.
User action: None.
PRICDDERR, prior severe CDD/Repository error
ERROR – There have been one or more severe CDD/Repository errors, and this may be the reason for the following errors.
User action: Recompile the program after correcting the first errors related to CDD/Repository.
PRIUSICLA, PRINT USING clause must be a string expression
ERROR – A PRINT USING statement specifies a numeric format string.
User action: Supply a valid format string.
PRIUSICON, PRINT USING conflicts with RECORD clause
ERROR – A PRINT USING statement contains a RECORD clause.
User action: Remove the RECORD clause or use the PRINT statement instead of PRINT USING.
PROSTRNES, program structures nested too deeply
FATAL – The program contains too many nested block constructs, for example, DEF function definitions.
User action: Reduce the number of nested block constructs.
PROTOOBIG, program too big to compile
FATAL – The program is too big.
User action: Recode the program as two or more modules.
PROWHINOT, exit from PROGRAM while not in a main program
ERROR – An EXIT PROGRAM statement was found in a program unit that is not a main program.
User action: Use the type of EXIT appropriate to the program unit.
QUALERR, unknown qualifier <name>
ERROR – An attempt was made to enter an invalid qualifier to a SET, LOCK, or COMPILE command.
User action: Enter the SET, LOCK, or COMPILE command with the correct qualifier.
RADNOTSUP, radix not supported
10 DECLARE LONG CONSTANT A = H"111"
User action: Specify a valid radix. See the VSI BASIC Reference Manual for a list of the radices VSI BASIC allows.
REAACCINC, READ access inconsistent with FOR OUTPUT
ERROR – An OPEN statement specifies FOR OUTPUT and ACCESS READ.
User action: FOR OUTPUT specifies that a new file is created; ACCESS READ specifies that the program can only read the file. If you want to create a new file, remove the ACCESS READ clause; if you want read-only access to a file, specify FOR INPUT.
READERR, error reading
<file-name>
ERROR – An error was detected in attempting to read a file.
User action: Supply a valid file specification or take corrective action based on the associated message.
REAWITDAT, READ without DATA statement
ERROR – The program contains a READ statement and there are no DATA statements.
User action: Supply a DATA statement or remove the READ statement.
RECENTARR, RECORD entire array must not have subfields specified
ERROR – A RECORD component reference specifies an array before the end of the component path, for example, A::B (,)::C.
User action: Remove the erroneous reference.
RECFILTOO, <field-name>
from
CDD/Repository has FILL too large
ERROR – The total size of a CDD/Repository record is greater than 65,535 bytes.
User action: Reduce the size of the record.
RECKEYQAD, entire RECORD or GROUP must be 8 bytes in length
ERROR – The user attempts to specify an entire RECORD or GROUP name in a key value field on a GET or FIND statement and the size of the structure does not match the size of the QUADWORD.
User action: When specifying a quadword key, use an 8-byte RECORD or GROUP; otherwise, specify the name of an elementary item in the RECORD or GROUP.
RECNOTBY, record may not be passed BY
<mechanism>
ERROR – The program attempts to pass a record to a subprogram using either the BY VALUE or BY DESC parameter-passing mechanism.
User action: Remove the passing mechanism, or specify BY REF. VSI BASIC programs can pass records only by reference.
RECNOTDEF, record type <name>
not
defined
ERROR – The program declares an instance of a user data type, but this type was not defined in the program module.
User action: Define the data type with a RECORD statement.
RECOVEMAP, RECORDSIZE overflows MAP
ERROR – An OPEN statement contains both a RECORDSIZE clause and a MAP clause, and the RECORDSIZE clause is larger than the MAP.
User action: Make the RECORDSIZE the same as the MAP size.
RECRECDEF, recursive RECORD definition of type
<name>
ERROR – The program contains two or more RECORD statements that reference each other.
User action: Change the program so that the RECORD statements do not point at each other.
RECTOBIGL, record too big from module
<mod-name>
in text library
<text-lib-name>
ERROR – the text library module specified in a %INCLUDE directive contains a record longer than 255 bytes.
User action: Extract the module from the text library, edit it to remove any records longer than 255 bytes, and replace the module in the text library.
RECTOOBIG, record too big from INCLUDE directive file
ERROR – The file specified in a %INCLUDE directive contains a record longer than 255 bytes.
User action: Edit the file to remove any records longer than 255 bytes.
RECTOOLAR, RECORD too large. Limit is 65,535 bytes
ERROR – The components of a RECORD definition add up to more than 65,535 bytes, or 32,767 bytes if the RECORD is used as an array component.
User action: Reduce the size of the RECORD definition.
REMARRREF, entire REMAPPED array <name>
cannot be passed BY REF
ERROR – The program attempts to pass an array declared in a MAP DYNAMIC statement to an external subprogram by reference.
User action: Entire remapped arrays must be passed by descriptor. Specify the BY DESC passing mechanism either in the EXTERNAL declaration or the subprogram invocation.
REMNOTALL, REM statement not allowed in programs without line numbers
ERROR – A REM statement has been found in a program without line numbers.
User action: Remove the REM statement.
REPLACE, assuming <operator(s)>
replaced
by<operator>
ERROR – The program contains a syntax error. VSI BASIC found incorrect or multiple operators where another single operator makes more sense, for example, 10 A == B. Compilation continues so that other errors can be detected. The actual program line remains unchanged and no object file is produced.
User action: Examine the line carefully to discover the error. Change the program line to correct the syntax error.
REQNUMEXP, <item>
requires a numeric
expression
ERROR – The program contains a string expression in a context requiring a numeric expression.
User action: Supply a numeric expression.
REQSTREXP, <item>
requires string
expression
ERROR – The program contains a numeric expression in a context requiring a string expression, for example, the file specification in an OPEN statement or the default file specification in a DEFAULTNAME clause.
User action: Supply a string expression.
RESABOCON, RESEQUENCE aborted due to conditional compilation
ERROR – A resequenced program contains a %IF-%THEN-%ELSE-%END-%IF directive.
User action: Remove the %IF-%THEN-%ELSE-%END-%IF directive.
RESABOSYN, RESEQUENCE aborted due to syntax error
ERROR – A RESEQUENCE operation was terminated because the program was not syntactically correct.
User action: Correct the syntax error and retry the RESEQUENCE operation.
RESATTINC, result attributes inconsistent with prior declaration
ERROR – An external or DEF function declaration specifies a data type for the function's result, which is different from the data type the DEF or FUNCTION statement specifies.
User action: Change the specified data type in either the declaration or the DEF or FUNCTION statement so that the data types agree.
RESINCLIN, RESEQUENCE cannot be used if INCLUDE files reference line numbers
ERROR – The current program references an INCLUDE file that contains line number references, for example, GOTO.
User action: Remove the %INCLUDE directive. VSI BASIC cannot resequence lines in an INCLUDE file.
RESLINGTR, RESEQUENCE cannot generate line numbers greater than 32,767
ERROR – The RESEQUENCE command specified an interval or starting point that would have created a line number greater than 32,767.
User action: Reduce the interval or the starting point.
RESNOTWHE, RESUME not allowed in WHEN block or handler
ERROR – A RESUME statement has been found in a WHEN block or an associated error handler.
User action: Remove the RESUME statement from the WHEN block or associated error handler.
RESORDLIN, RESEQUENCE cannot change the order of or delete lines
ERROR – The RESEQUENCE command specifies invalid source program changes.
User action: Supply a valid RESEQUENCE command.
RETCONMUS, RETRY and CONTINUE must appear in error handlers
ERROR – A RETRY or CONTINUE statement is not in an error handler associated with a WHEN block protected region.
User action: Remove the RETRY or CONTINUE statement.
RFAEXPREQ, RFA expression required
ERROR – A GET BY RFA statement contains an expression that is not of the RFA data type.
User action: Supply a valid RFA expression.
RFANOTALL, RFA not allowed in this context
ERROR – The program attempts to use an RFA expression in an arithmetic expression or other invalid context.
User action: Remove the RFA expression. You can use the RFA data type only in file I/O, in an assignment statement, or in a comparison.
ROUSUPDEC, ROUNDing supported only for DECIMAL
ERROR – Rounding was specified for a non-DECIMAL data type in: 1) a compiler command, 2) a qualifier to the BASIC DCL command, or 3) an OPTION statement.
User action: Specify rounding only for the DECIMAL data type.
RPTCOUMUS, repeat count must be positive numeric
ERROR – A FILL item specifies a nonnumeric or negative repeat count, for example, FILL(A$) or FILL(-3).
User action: Supply a valid repeat count.
SCAFACINH, SCALE factor inhibits optimization
INFORMATION – This error is reported only when the /SETUP qualifier is in effect. Specifying a scale factor prevents optimization of the compiler-generated code.
User action: Compile the program without specifying a scale factor.
SCAFILMUS, ANALYSIS file must be random access – no ANA file produced
WARNING – The file specification on the /ANALYSIS_DATA qualifier specifies a nonrandom access device; therefore, no analysis data file will be produced. VSI BASIC ignores the /ANALYSIS_DATA qualifier and continues compilation.
User action: Specify a random access device on the file specification on the /ANALYSIS_DATA qualifier.
SCALE0, scale factor used is 0 for single precision
WARNING – An attempt was made to set the SCALE factor while in single precision.
User action: Set the precision to /REAL_SIZE = DOUBLE. You cannot use scaling when in single precision.
SCANOTANS, /ANALYSIS_DATA qualifier not allowed with /ANSI
ERROR – The /ANALYSIS_DATA qualifier conflicts with the /ANSI_STANDARD qualifier.
User action: Specify either the /ANALYSIS_DATA qualifier or the /ANSI_STANDARD qualifier, but not both.
SCAOUTRAN, SCALE is out of range. Valid is 0 to 6.
ERROR – The OPTION statement specifies a scale factor that is not from 0 to 6, inclusive.
User action: Supply a valid scale factor.
SEQERR, attempt to sequence over existing statement
ERROR – A SEQUENCE command specifies a starting line number that already exists in the VSI BASIC source program in memory.
User action: Specify a starting line number higher than any existing line or delete the old statement before using the SEQUENCE command.
SEVERRSCA, please submit an SPR ---- internal error in SCA support
FATAL – A severe error has been detected in the SCA support in the VSI BASIC compiler. If you recompile your program without the /ANALYSIS_DATA qualifier, this error should no longer occur.
User action: Please submit a software problem report (SPR) with the source code of a small program that produces the error.
SEVINTERR, severe internal error has been detected. Submit an SPR.
FATAL – An error has been detected in the VSI BASIC compiler.
User action: Please submit a software problem report (SPR) with the source code of a small program that produces this error.
SHRNOTAVL, Unable to access the shareable image
<name>
ERROR – The shareable image is not available on your system.
User action: Install the correct version of the required shareable image.
SPANOSPA, SPAN is inconsistent with NOSPAN
WARNING – An OPEN statement specifies both SPAN and NOSPAN.
User action: Remove one of the clauses.
SPELL, assuming <item>
intended to be
the keyword: keyword
ERROR – The program contains a syntax error. VSI BASIC assumes that a keyword has been misspelled, and compilation continues so that other errors can be detected. The actual program line remains unchanged and no object file is produced.
User action: Examine the line carefully to discover the error. Change the program line to correct the syntax error.
SPENUMEXC, specified numeric exceeds valid character code
ERROR – A quoted literal of type character (C) contains a value outside the valid range, for example, ’300 ’C.
User action: Use a valid ASCII value.
STACKOVF, stack frame overflow for variables
ERROR – The program requires too much space for dynamic variables.
User action: Reduce the number of dynamic variables or place some of the variables in a MAP or COMMON.
STANOTALL, statement not allowed within a PICTURE definition
ERROR – The statement you specified is not allowed in a PICTURE definition.
User action: Remove the statement from the PICTURE definition.
STARISNEE, star (*) is needed in DEF, not “/”
ERROR – The program contains a statement that starts with DEF/.
User action: Change the DEF/ to DEF*.
STRARRNOT, string array not ANSI
INFORMATION – A program compiled with the /ANSI_STANDARD qualifier contains a string array.
User action: Remove the string array.
STRCONEXP, string constant expression is too long
ERROR – The program contains a DECLARE STRING CONSTANT statement where the value assigned to the constant exceeds the maximum number of characters allowed for string constant expressions. The maximum length of a string constant expression at compile time is 498 characters.
User action: Change the string constant to a string variable and assign the string expression to the variable at run time.
STRCONREQ, string constant required
DECLARE STRING CONSTANT ABC = 123
User action: Supply a string literal or a named string constant.
STRDEFNOT, string DEF not ANSI
INFORMATION – A program compiled with the /ANSI_STANDARD qualifier contains a string DEF.
User action: Remove the string DEF.
STRLENANY, string length not allowed on ANY
ERROR – An ANY parameter specifies a string length in an EXTERNAL statement. This is not allowed because ANY implies that you can use any data type, not specifically a string data type.
User action: Remove the string length specification from the ANY clause.
STRIS_NEE, string expression is required
ERROR – The program contains a numeric expression where a string expression is needed, for example, NAME 1% AS “ABC.DAT”.
User action: Supply a string expression.
STRLENDYN, string length not allowed on MAP DYNAMIC variable
ERROR – A string variable in a MAP DYNAMIC statement specifies a string length.
User action: Remove the string length. All string variables named in a MAP DYNAMIC statement have a length of zero until a REMAP statement executes.
STRLENINC, virtual array string <name>
length increased from <n>
to
<m>
WARNING – In a string virtual array DIM statement, the specified string length is not a power of two.
User action: None. VSI BASIC increases the string length to the next higher power of two.
STRLENMUS, string length specification for
<name>
must be numeric
ERROR – The length specification for a fixed-length string is nonnumeric, for example, COMMON A$ = “ABC”.
User action: Supply a numeric length specification.
STRLENNOT, string length not allowed on numeric variable
<name>
ERROR – The declaration for a numeric variable contains a string length specification.
User action: Remove the string length specification.
STRLENTRU, virtual array string <name>
length truncated from <n>
to
<m>
WARNING – A string virtual array specifies a string length greater than 512. VSI BASIC truncates the length specification to 512.
User action: None. The maximum string length for virtual arrays is 512.
STRLITREQ, string literal required for compiler directive
ERROR – A quoted string is missing in a compiler directive that requires one, for example, %IDENT.
User action: Supply a string literal for the compiler directive.
STROUTRAN, string is too large
ERROR – A string exceeds the maximum allowable length. The maximum length is 65,535 characters.
User action: Reduce the length of the string.
STRRECFIE, string record element may not be FIELDed
ERROR – A FIELD statement contains a string record element as the fielded variable.
User action: Replace the string record element with a dynamic string. Fielded variables must be dynamic.
STRRECFOR, stream format must have sequential organization
ERROR – A file was opened using STREAM as a record format, but the specified organization was not SEQUENTIAL.
User action: Change the OPEN statement so that it specifies ORGANIZATION SEQUENTIAL.
STRVAREXP, string variable expected
ERROR – A CHANGE statement specifies a numeric variable.
User action: Supply a string variable; the CHANGE statement changes a string variable to a numeric array and vice versa.
STRVARREQ, string variable required
ERROR – A statement references a numeric variable instead of a string variable, for example, LINPUT A%.
User action: Supply a string variable instead of a numeric variable.
SUBMAYNOT, subscript may not be specified for entire array
ERROR – A CALL statement or external function reference passes an entire array as a parameter and contains a subscript expression, for example, A(,,3).
User action: Remove the subscript expression. You cannot specify any subscripts when passing an entire array as a parameter.
SUBOUTRAN, subscript out of range for
<array-name>
ERROR – The program references an array element with constant subscript(s) outside the bounds of the array.
User action: Check program logic to make sure all subscripts are within the bounds of the array.
SUBRECCOM, subscripting error in RECORD component
ERROR – The program contains a RECORD component reference with invalid subscripts, for example, A::B(1,2)::C where B has only one subscript, or A::B where A requires a subscript.
User action: Change the erroneous reference. You must specify as many subscripts as were defined in the RECORD.
SUBWHINOT, exit from SUB seen while not in SUB
ERROR – A program contains an EXIT SUB or SUBEXIT statement with no preceding SUB statement.
User action: If the program is a subprogram, supply a SUB statement; otherwise, remove the EXIT SUB or SUBEXIT statement.
SUFFILNOT, suffix not allowed on FILL after datatype keyword
ERROR – A FILL item defined with an explicit data type ends in a percent or dollar sign.
User action: Remove the FILL item's percent or dollar sign.
SUFINTONLY, % only allowed with BYTE, WORD, LONG, QUAD, or INTEGER keywords
ERROR – The % suffix is only allowed on integer data types.
User action: Remove the % suffix from the variable name or change the data-type keyword.
SUFNOTALL, suffix not allowed on variable
<name>
ERROR – A name, which cannot end in a percent sign or dollar sign, such as a label name, ends with either a percent sign or dollar sign.
User action: Remove the variable's percent or dollar sign.
SUFNOTHAN, suffix not allowed on HANDLER
<name>
ERROR – A HANDLER name ends in a percent or dollar sign.
User action: Remove the percent or dollar sign from the HANDLER name.
SUFNOTREC, suffix not allowed for record type
ERROR – A record definition specifies a user-defined record type that ends in a percent or dollar sign.
User action: Remove the record type's percent or dollar sign.
SUFSTRONLY, $ is only allowed with STRING keyword
ERROR – The $ suffix is only allowed on string data types.
User action: Remove the $ suffix from the variable name or change the data-type keyword.
SYNNOTANS, syntax check mode not allowed when ANSI
ERROR – A SET /SYNTAX_CHECK command was entered when the /ANSI_STANDARD qualifier was in effect.
User action: None; syntax checking is not supported in ANSI mode.
SYSERROR, system service error
ERROR – An error was detected while executing a system service.
User action: Take corrective action based on the associated message.
TEXFOLEND, text following end of program unit must be on new
<type of line>
line
ERROR – The compiler detected text following an END, END SUB, or END FUNCTION statement.
User action: Remove the text. In a multimodule source file with line numbers, any text following an END, END SUB, or END FUNCTION statement must begin on a numbered line. In a multimodule source file without line numbers, any text following an END, END SUB, or END FUNCTION statement must begin on a new physical line.
TEXLINMSG, text line exceeded 255 characters
INFORMATION – An input line contains more than 255 characters. VSI BASIC saves the first 255 input characters into the line buffer and ignores the rest of the input.
User action: Supply no more than 255 characters per input line to avoid truncation of input.
TEXPATMUS, text path must be “RIGHT”, “LEFT”, “UP” or “DOWN”
ERROR – You specified an invalid value for the path specification of the SET TEXT PATH statement.
User action: Specify one of the values listed in the message.
TEXPREMUS, text precision must be “STROKE”, “CHAR” or “STRING”
ERROR – You specified an invalid value for the text precision of the SET TEXT FONT statement.
User action: Specify one of the values listed in the message.
THEMUSFOL, THEN directive must follow a lexical expression
ERROR – A %IF directive contains a lexical expression that is not immediately followed by a %THEN clause.
User action: Supply a %THEN clause. %THEN, %ELSE, and %END %IF are required in a %IF directive.
TOMCHINFO, extra information about command line has been ignored
INFORMATION – You supplied an argument to a CONTINUE, EXIT, IDENTIFY, or SCRATCH command. These commands do not accept arguments. VSI BASIC ignores the extra data and executes the command.
User action: Remove the argument from the command.
TOOFEWARG, too few arguments
ERROR – The invocation of a VSI BASIC built-in function contains too few arguments.
User action: Supply the correct number of arguments to the function.
TOOMANARG, too many arguments
ERROR – The invocation of a VSI BASIC built-in function contains too many arguments.
User action: Supply the correct number of arguments to the function.
TOOMANIND, too many array indices active
ERROR – A subscript expression contains more than 100 array indices between the open parenthesis and the close parenthesis.
User action: Reduce the number of active array indices.
TOOMANKEY, too many keys – limit is 255
ERROR – An OPEN statement specifies more than 255 index keys.
User action: Reduce the number of index keys. The maximum is 255.
TOOMANPAR, too many function parameters active
ERROR – An external function invocation contains too many expressions in the actual parameter list.
User action: Reduce the number of expressions in the actual parameter by assigning the expressions to temporary variables.
TRAFUNONL, Transformation functions only permitted with multiplication
ERROR – A graphics transformation function is used in a MAT statement other than matrix multiplication.
User action: Remove the transformation function from the MAT statement.
TRAOUTRAN, transformation number must be in the range 1 - 255
ERROR – You specified a transformation number that is less than 1 or greater than 255.
User action: Change the transformation number to be within the range 1 to 255.
TYPDEFSTR, TYPE default of STRING is not allowed
ERROR – STRING was specified as the default data type in: 1) a compiler command, 2) a qualifier to the DCL BASIC command, or 3) an OPTION statement.
User action: Specify a numeric data type as the default.
UNCALLED, Routine <routine> can never be called
INFORMATION – The compiler has detected a routine that is never called.
User action: Review the program to determine if the routine is needed. If it is not, you may want to remove it.
UNDEFINED, unresolved/undefined symbols
ERROR – A program executed in the VAX BASIC Environment calls or invokes a subprogram or routine that has not been loaded.
User action: Load the subprogram or routine before running the program in the VAX BASIC Environment.
UNDLINNUM, undefined line number
ERROR – A statement tries to transfer control to a nonexistent line. Or, in a numberless program, a line number is referenced.
User action: Replace the nonexistent line number with the correct destination line number or label.
UNELEXDIR, unexpected lexical directive encountered
ERROR – The specified lexical directive is not legal in this statement.
User action: Use a supported lexical directive.
UNEXPEOF, unexpected end of file
ERROR – An end-of-file was specified immediately after an ampersand continuation character.
User action: Remove the ampersand continuation character or continue the line.
UNINIT, variable <variable> is fetched, not initialized
INFORMATION – The compiler has detected a variable that is used but not initialized.
User action: Review the program to determine if the variable should be initialized before use. If necessary, you may want to add code to initialize the variable.
UNKCOMINP, unknown command input
ERROR – An attempt was made to enter an invalid or unknown command.
User action: Enter the VSI BASIC command correctly.
UNLINCREA, UNLOCK EXPLICIT clause inconsistent with ACCESS READ
ERROR – An OPEN statement contains both an ACCESS READ and an UNLOCK EXPLICIT clause. This is inconsistent because ACCESS READ specifies no record locking while UNLOCK EXPLICIT specifies that all accessed records remain locked until explicitly unlocked.
User action: Either remove the UNLOCK EXPLICIT clause or change the ACCESS clause.
UNREACH, code can never be executed at label
<label>
INFORMATION – The compiler has detected code that will never be executed, for example, a multistatement line whose first statement is a GOTO, EXIT, ITERATE, RESUME, or RETURN. (Alpha BASIC only)
User action:Review the program to determine if the code should be executed. If you determine the code should be executed, then you should revise the program flow logic accordingly; otherwise, the code is unnecessary, and you may want to remove it. In the case of the GOTO, EXIT, ITERATE, RESUME, or RETURN statements, make sure that these statements are the only statements on the line, or the last statement on a multistatement line.
UNSCDDLEV, unsupported CDD/Repository level
<number>
. Supported level is
<number>
.
ERROR – The current CDD/Repository version is incompatible with VSI BASIC.
User action: Use a supported version of CDD/Repository.
UNTSTRLIT, unterminated string literal
ERROR – The program contains an improperly terminated string literal; for example, "ABC , "ABC ’, and ’ABC" are all improperly terminated.
User action: Use the same type of quotation mark (either single or double) for both beginning and ending string delimiters.
USEONLALO, USE only allowed inside WHEN blocks
ERROR – A USE statement is not within a WHEN block.
User action: Remove the USE statement.
USERABORT, user ABORT directive
<text>
FATAL – The compilation was terminated as the result of a %ABORT directive. The compiler prints the text following the %ABORT.
User action: None.
USERPRINT, <text>
SUCCESS – The compilation found a %PRINT directive and printed the specified message to the terminal and listing file.
User action: None.
USEVARNOT, user variable <name>
not
allowed in declaration
ERROR – The parameter list in an external subprogram declaration contains a user variable name.
User action: Remove the variable from the parameter list. When declaring a routine, the parameter list can contain only data type and parameter-passing mechanism specifications.
VALTOOLAR, value too large for constant
WARNING – The value of an EXTERNAL CONSTANT is larger than the specified data type allows.
User action: Make sure the data type specified in the EXTERNAL CONSTANT statement matches that of the actual constant.
VALUEREQ, PRINT USING requires a value
ERROR – A PRINT USING statement must have at least one expression or value.
User action: Supply an expression or value at the end of the PRINT USING statement.
VARCONREQ, variable or constant required
ERROR – The program contains an executable DIM statement that contains an expression in the bounds list.
User action: Remove the expression from the bounds list. Executable DIM statements can have only constants or variables (simple or subscripted) as bounds.
VARNOALGN, Variable <name>
within
COMMON or MAP is not naturally aligned.
WARNING – Identifies a variable within a COMMON or MAP that was found not to be naturally aligned. This error is only reported when the /WARNING=ALIGNMENT qualifier is in effect.
User action: Modify COMMON or MAP so that all variables are naturally aligned.
VERJUSMUS, vertical justification must be “TOP”, “CAP”, “HALF”, “BASE”, “BOTTOM” or “NORMAL”
ERROR – You specified an invalid value for the vertical component of the SET TEXT JUSTIFY statement.
User action: Specify one of the values listed in the message.
VIRARROVF, virtual array space exceeded at array
<name>
ERROR – The storage for virtual arrays on a single channel exceeds 2,147,483,647 bytes.
User action: If there is only one virtual array on the channel, you must reduce the amount of storage used by the array. However, if there is more than one virtual array on the channel, you can put each array on a separate channel.
VIRNOTALL, virtual array not allowed in graphics statements
ERROR – You specified an entire virtual array on a statement that does not allow them.
User action: Specify a nonvirtual array in place of the virtual array.
VIRRECTOO, virtual RECORD <name>
is too
large. Limit is 512 bytes
ERROR – The elements of a virtual array are of type
<name>
and the total storage requirement for each
element is greater than 512 bytes.
User action: Reduce the size of the RECORD.
WRITEERR, error writing <file-name>
ERROR – An error was detected in attempting to write to a file.
User action: Supply a valid file specification or take corrective action based on the associated message.
WROTYPLIB, library <lib-name>
is not an
OBJECT or IMAGE library
WARNING – The logical BASIC$LIBn translates to a library that is not an object library or a shareable image library.
User action: Change the logical BASIC$LIBn to translate to an object library or a shareable image library.
XYPOIREQ, X,Y point required between semicolons
ERROR – In a list of points in a statement such as PLOT LINES, you specified two semicolons in a row without an X,Y point specification between them.
User action: Either supply another point or remove the extra semicolon.
Appendix B. Run-Time Messages
VSI BASIC returns run-time messages if an error occurs while a program is executing. The error is diagnosed and for programs without line numbers, VSI BASIC indicates the program line that generated the error. Warning messages indicate that an error has occurred, but program execution continues.
In some cases, VSI BASIC performs the specified operation, but the results are not as expected. Fatal (severe) error messages indicate that the program has aborted. You can recover from most fatal errors by including error-handling routines in your program and by specifying OPTION HANDLE = SEVERE. Certain errors, however, are not recoverable even when error-handlers are used. In the descriptions of these errors, they are designated as not able to be trapped. You do not need error-handling routines to trap errors that generate warning messages.
Section B.1, “VSI BASIC for OpenVMS Run-Time Errors by Mnemonic” lists VSI BASIC for OpenVMS run-time errors, alphabetized by mnemonic code. Section B.2, “VSI BASIC for OpenVMS Run-Time Errors by Number” is a cross-reference numerical listing of run-time errors generated by VSI BASIC for OpenVMS. Section B.3, “Errors Not Generated by VSI BASIC for OpenVMS” lists messages that VSI BASIC for OpenVMS does not generate, but which can be displayed with the ERT$ function. See the VSI BASIC Reference Manual for information about RMSSTATUS and VMSSTATUS.
B.1. VSI BASIC for OpenVMS Run-Time Errors by Mnemonic
%BAS-<l>-<mnemonic>, <message>
-BAS-I-FROLINMOD, from Line x in module y
<l>
I – Indicating information
W – Indicating a warning
E – Indicating an error
F – Indicating a severe error
<mnemonic>
Is a 3- to 9-character string that identifies the error.
<X>
Is the line number where the error occurred.
<Y>
Is the name of the module where the error occurred.
Warning error messages indicate that an error has occurred, but program execution continues. In some cases, VSI BASIC for OpenVMS reprompts for more information or correct data; in other cases, VSI BASIC for OpenVMS performs the specified operation, but the results are not as expected. Fatal error messages indicate that the program has aborted.
ARGDONMAT, Arguments don't match (ERR=88)
The proper array descriptor was not specified for a matrix operation.
User action: Use VSI BASIC for OpenVMS to create the array.
ARGTOOLAR, Argument too large in EXP (ERR=49)
An argument to the EXP function larger than 88
An exponentiation operation that results in a number greater than 1E38
User action: Change the EXP argument to be in the valid range, or reduce the size of the exponent.
ARRMUSSAM, Arrays must be same dimension (ERR=238)
The program attempts to perform matrix addition or subtraction on input arrays with a different dimensions.
User action: Use arrays that have identical dimensions.
ARRMUSSQU, Arrays must be square (ERR=239)
The program attempts matrix inversion (MAT INV) on an array that is not inversible.
User action: Use only square arrays when performing a matrix inversion.
ARRTOOSMA, Array too small (ERR=197)
The array you referenced with a graphics statement is too small. Check the description of the graphics statement to get the minimum size requirement for the array.
User action: Increase the size of the array.
BADDIRDEV, Bad directory for device (ERR=1)
The device directory does not exist or is unreadable.
User action: Supply a valid directory.
BADRECIDE, Bad record identifier (ERR=143)
A zero or negative record number on a RELATIVE file
A null key value on an INDEXED file
User action: Change the record number or key specification to a valid value.
BADRECVAL, Bad RECORDSIZE value on OPEN (ERR=148)
The value in the RECORDSIZE clause in the OPEN statement either 1) is zero or greater than 65,535 or 2) does not match the record size of an existing file.
User action: Change the value in the RECORDSIZE clause.
CANCHAARR, Cannot change array dimensions (ERR=240)
The program attempts to redimension an array to a different number of dimensions.
User action: Change the arrays dimensions in the DIM or MAT statement.
CANFINFIL, Cannot find file or account (ERR=5)
The specified file or directory is not present on the device.
User action: Supply a valid file specification.
CANINVMAT, Cannot invert matrix (ERR=56)
The program attempts to invert a single-dimension matrix.
User action: Supply a matrix of the proper form for inversion.
CANOPEFIL, Cannot open file (ERR=162)
The program attempts to open a file that cannot be opened.
User action: Use VMSSTATUS to determine the RMS failure that caused the error.
CLIPONOFF, Clipping must be set to ON or OFF (ERR=259)
Valid strings for the SET CLIP statement are “ON” and “OFF.”
User action:Change the string to either “ON” or “OFF.”
COLNOTCON, Color indices are not contiguous (ERR=261)
The color indices on the device you are using are not contiguous.
User action: Unlike most devices, all color indices between zero and the number returned by the ASK MAX COLOR statement are not available on this device.
COONOTNDC, Coordinates are not within NDC space (ERR=273)
The boundaries of NDC space are 0,1,0,1; coordinates must be within this range.
User action:Supply coordinates with values from 0 to 1. Make sure that the minimum value of x is less than the maximum value of x and that the minimum value of y is less than the maximum value of y.
CORFILSTR, Corrupted file structure (ERR=29)
RMS has detected an invalid file structure on disk.
User action: See your system manager.
DATFORERR, Data format error (ERR=50)
The program specifies a data type in a statement that does not agree with the value supplied or invalid data was used in string arithmetic.
User action: Change the statement or supply data of the correct type.
DATOVERF, data overflow (ERR=289)
The keystroke retrieved by the INKEY$ function caused the type-ahead buffer to overflow or the terminal attempted to send a valid ANSI escape sequence that did not correspond to a keystroke.
User action: Specify the DCL command SET TERMINAL/HOSTSYNC before using the INKEY$ function. This command will prevent the type-ahead buffer from overflowing.
DATTYPERR, Data type error (ERR=101)
The program attempts to access a parameter passed BY DESC (by descriptor), and the descriptor contains an incorrect data type. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: Check the program code that created the passed parameter and make sure it creates a parameter of correct data type.
DEADLOCK, Detected deadlock while waiting for GET or FIND (ERR=193)
The record your program is trying to access is currently locked on another channel or by another process. Simultaneously, your program has locked a record that the other user cannot access. The deadlock cannot be resolved.
Use the FREE statement to unlock all locked records
Use GET...REGARDLESS if read access is sufficient
DECERR, DECIMAL error or overflow (ERR=181)
The result of a DECIMAL expression is greater than or requires more precision than can be contained in the variable.
User action: Reduce the magnitude of the expression or increase the allowed digits in the DECIMAL variable.
User action: Check program logic or trap the error in an error handler.
DEVHUNWRI, Device hung or write locked (ERR=14)
The program attempted an operation to a hardware device that is not functioning properly or is protected against writing.
User action: Check the device on which the operation is performed.
DEVINMET, Device is an input metafile (ERR=270)
The operation cannot be performed on an input metafile (device type 3).
User action: Specify the device ID for a device other than an input metafile.
DEVNOTOPE, Device is not open (ERR=268)
The device has not been identified in an OPEN...FOR GRAPHICS statement.
User action:Specify the device ID number in an OPEN...FOR GRAPHICS statement.
DEVOPEINC, Device and operation are incompatible (ERR=272)
The operation you requested cannot be performed on the specified device. For example, output cannot be dislayed on a device that is for input only.
User action:Specify the device ID for a device with the appropriate compatibility. Device types are listed in Programming with VAX BASIC Graphics.
DEVOUTMET, Device is an output metafile (ERR=269)
The specified device is an output metafile (device type 2).
User action: Specify the device ID for a device other than an output metafile.
DEVTYPNOT, Device type is not supported (ERR=267)
The specified device type is not supported by Compaq GKS for OpenVMS.
User action:Specify an alternative device type. Standard supported device types are listed in Programming with VAX BASIC Graphics and in the Compaq GKS for OpenVMS documentation. Verify with your system manager that support for the specified device has been installed. Also, verify that the Compaq GKS for OpenVMS startup command procedure has properly executed.
DIFUSELON, Differing use of LONG/WORD or SINGLE/DOUBLE qualifiers (ERR=229)
The main and subprograms were compiled with different LONG/WORD modes. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: Recompile one of the programs with the same qualifier as the other.
DIMOUTRAN, Dimension number out of range (ERR=195)
The upper or lower bound of the specified dimension cannot be returned because the array has fewer dimensions than the one requested.
User action:Change the dimensions specified with the LBOUND or UBOUND function.
DIRERR, Directive error (ERR=253)
A system service call resulted in an error.
User action: See the VSI OpenVMS I/O User's Reference Manual or the VSI OpenVMS Record Management Services Reference Manual.
DIVBY_ZER, Division by 0 (ERR=61)
The program attempts to divide a value by zero.
User action: Check program logic and change the attempted division or trap the error in an error handler.
DUPKEYDET, Duplicate key detected (ERR=134)
In a PUT operation to an indexed file, a duplicate key was specified, and DUPLICATES was not specified when the file was created.
User action: Change the duplicate key, or recreate the file specifying DUPLICATES for that key.
ECHTYPNOT, Prompt/echo type not supported (ERR=256)
The specified prompt or echo type is invalid. VSI BASIC for OpenVMS supports only the default prompt and echo types.
User action:Do not change the prompt or echo type. If you do so, you should continue to use direct calls to Compaq GKS routines rather than use VSI BASIC for OpenVMS input statements.
ENDFILDEV, End of file on device (ERR=11)
The program attempted to read data beyond the end of the file.
User action: None. The program can trap this error in an error handler.
ENTPOINOT, Entered points not within a transformation (ERR=285)
Input points are not within the viewport of a defined transformation.
User action:Issue a warning to the user to input points within the defined area. Alternatively, you can change at least one transformation to include the viewport area not defined. At the start of program execution, transformation 1 includes all of NDC space. Optionally, you can define one transformation to cover the default viewport.
ERRFILCOR, Error on OPEN - file corrupted (ERR=178)
The program attempted to open an invalid structure on disk.
User action: See your system manager.
ERRTRANEE, ERROR trap needs RESUME (ERR=246)
An error handler attempts to execute an END, END SUB, END FUNCTION, SUBEND, FUNCTIONEND, or FNEND statement without first executing a RESUME statement. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: Change the program logic so that the error handler executes a RESUME statement before executing an END, END SUB, END DEF, SUBEND, FUNCTIONEND, or FNEND statement.
FATSYSIO_, Fatal system I/O failure (ERR=12)
An I/O error has occurred in: 1) the system or 2) Record Management Services. The last operation will not be completed.
User action: See the OpenVMS System Messages and Recovery Procedures Reference Manual for RMS errors or retry the operation. Use VMSSTATUS to return the VMS condition code that caused the error.
FIEOVEBUF, FIELD overflows buffer (ERR=63)
A FIELD statement attempts to access more data than exists in the specified buffer.
User action: Change the FIELD statement to match the buffer's size, or increase the buffer's size.
FILACPFAI, FILE ACP failure (ERR=252)
The operating system's file handler reported an error to RMS.
User action: See the VSI OpenVMS I/O User's Reference Manual or the VSI OpenVMS Record Management Services Reference Manual.
FILATTNOT, File attributes not matched (ERR=160)
ORGANIZATION
BUCKETSIZE
BLOCKSIZE
Key number, size, position, or attributes (CHANGES and DUPLICATES)
Record format
User action: Change the OPEN statement attributes to match those of the file or remove the clause.
FILEXPDAT, File expiration date not yet reached (ERR=174)
The program attempted to delete a file before the file's expiration date was reached.
User action: Change the file's expiration date.
FILIS_LOC, File is locked (ERR=138)
The program does not allow shared access, and attempts to access a file that has been locked by another user or by the system.
User action: Change the OPEN statement to allow shared access or wait until the file is released by other users.
FLOPOIERR, Floating point error or overflow (ERR=48)
A program operation resulted in a floating-point number with absolute value outside the allowable range for that data type.
User action: Check program logic or trap the error in an error handler.
FNEWITFUN, FNEND without function call (ERR=73)
The program executes an END DEF or FNEND statement before executing a function call. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: Check program logic to make sure that END DEF or FNEND statements are executed only in multiline DEFs or remove the END DEF or FNEND statement.
GKSNOTINS, DEC GKS FOR VMS is not installed (ERR=226)
Graphics statements are not operational when Compaq GKS is not installed.
User action:See your system manager.
ILLALLCLA, Illegal ALLOW clause (ERR=168)
The value specified for the ALLOW clause (sharing) on the OPEN statement is illegal for the type of file organization.
User action: Change the ALLOW clause argument.
ILLARGLOG, Illegal argument in LOG (ERR=53)
The program contains a negative or zero argument to the LOG or LOG10 function.
User action: Supply an argument in the valid range.
ILLARESTY, Illegal area style (ERR=262)
SOLID (the default)
HOLLOW
HATCH
PATTERN
User action:Specify a valid area style for the device.
ILLBYTCOU, Illegal byte count for I/O (ERR=31)
A PRINT or INPUT list invoked a function that closed an I/O channel.
User action: Change the function so that it does not close the I/O channel.
ILLCNTCLA, Illegal count clause (ERR=290)
In a graphics statement, you specified a COUNT clause with a numeric value that exceeds the size of the array.
User action: Specify a numeric value that is less than or equal to the size of the array.
ILLCOLIND, Illegal color index (ERR=280)
The index you specified is not supported by the device.
User action:Specify a valid color index. The valid range of indices for the device is from 0 to the value retrieved by the ASK MAX COLOR statement.
ILLCOLMIX, Illegal color mix (ERR=291)
The color mix value specified on the SET COLOR MIX statement is outside the range of 0 to 1.
User action: Specify a value from 0 to 1.
ILLDEVID, Illegal device identification number (ERR=266)
The device identification number is beyond the valid range of 0 through 255.
User action:Specify a device identification number between 0 and 255.
ILLDEVNAM, Illegal device name in OPEN (ERR=292)
Specifying a device that does not exist on the system
Specifying a logical name that is not defined
Specifying a file name that does not exist when the device type is for an input metafile
Specifying a file name for a device type that requires an OpenVMS physical device name
User action: Specify an appropriate device name.
ILLECHARE, Illegal echo area (ERR=283)
The specified echo area boundaries are invalid.
User action:Specify echo area boundaries within the device viewport.
ILLEXIDEF, Illegal exit from DEF* (ERR=245)
A multiline DEF* contains a branch to an END, END SUB, END DEF, SUBEND, or FUNCTIONEND statement. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: Change the program logic so that the program executes the multiline function's END DEF or FNEND statement before executing the END, END SUB, END DEF, SUBEND, or FUNCTIONEND statement.
ILLFIEVAR, Illegal FIELD variable (ERR=122)
A FIELDed variable is referenced after a non-BASIC subprogram closed the file associated with that variable. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: Check program logic; do not reference the variable after the file has been closed.
ILLFILNAM, Illegal file name (ERR=2)
A file name is: 1) too long, 2) incorrectly formatted, or 3) contains embedded blanks or invalid characters.
User action: Supply a valid file specification.
ILLILLACC, Illegal or illogical access (ERR=136)
The attempted record operation and the ACCESS clause in the OPEN statement are incompatible.
The ACCESS clause is inconsistent with the file organization.
ACCESS READ or APPEND was specified when the file was created.
User action: Change the ACCESS clause.
ILLINIVAL, Illegal initial value (ERR=284)
The current initial value specified on the SET INITIAL VALUE or LOCATE VALUE statement is beyond the range of possible values.
User action:Specify an initial value within the default range (0 through 1) or within the alternative range you optionally specified, or change the range limits.
ILLIO_CHA, Illegal I/O channel (ERR=46)
The program specified an I/O channel outside the legal range.
User action: Specify I/O channels in the range 1 to 99, inclusive or one returned from LIB$GET_LUN.
ILLKEYATT, Illegal key attributes (ERR=137)
The program specified CHANGES for the primary key.
User action: Remove the CHANGES specification from the primary key. You can specify CHANGES only for alternate keys.
ILLLINSIZ, Illegal line size (ERR=275)
The specified line size is less than or equal to zero.
User action:Specify a line size value greater than zero.
ILLLINSTY, Illegal line style number (ERR=274)
The specified line style number is less than or equal to zero.
User action:Specify a valid line style value greater than zero.
ILLNETOPE, Illegal network operation (ERR=190)
The program tries to mix GET and PUT operations, or PRINT and INPUT operations, on a remote terminal-format file.
User action:Change the file organization when opening the file to be sequential variable.
ILLNUM, Illegal number (ERR=52)
A value supplied to a numeric variable is incorrect, for example, “ABC” and “1..2” are illegal numbers.
User action: Supply numeric values of the correct form.
ILLOPE, Illegal operation (ERR=141)
DELETE a record in a sequential file.
UPDATE a record on a magtape file.
Rewind a process-permanent file.
DELETE a record in a read-only file.
Assign a value to a virtual array element in a read-only file.
Perform a MARGIN operation on VIRTUAL file.
Transpose a matrix, or perform a matrix multiplication, with the same array as source and destination.
Perform an invalid operation on a VIRTUAL file, for example, using GET and PUT on a VIRTUAL file, then attempting to reference a virtual array dimensioned on that file.
User action: Change the illegal operation.
ILLPICOPE, Illegal picture operation (ERR=258)
SET WINDOW
SET VIEWPORT
SET DEVICE WINDOW
SET DEVICE VIEWPORT
SET TRANSFORMATION
SET INPUT PRIORITY
SET CLIP
User action: Remove any invalid statements from the picture definition. Set the boundaries for windows and viewports before a picture is invoked.
ILLPOISTY, Illegal point style number (ERR=276)
The specified point style is less than or equal to zero.
User action:Specify a valid point style greater than or equal to zero.
ILLRECACC, Illogical record accessing (ERR=152)
The program attempts to perform an operation that is invalid for the specified file type, for example, a random access on a sequential file.
User action: Supply a valid operation for that file type or change the file type.
ILLRECFIL, Illegal record on file (ERR=142)
A record contains an invalid byte count field.
User action: Use the DCL command DUMP to check the file for possible bad data.
ILLRECLOC, illegal record locking (ERR=187)
The program contains an ALLOW clause on a GET statement and the file was not opened with the UNLOCK EXPLICIT clause. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: Either remove the ALLOW clause from the GET statement or use the UNLOCK EXPLICIT clause in the OPEN statement.
ILLRESSUB, Illegal RESUME to subroutine (ERR=247)
While in an error handler activated by an ON ERROR GO BACK, the error handler attempts to RESUME without a line number. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: None; you cannot specify the RESUME statement without a line number in any program module except in the program module containing the error handler.
ILLSTYIND, Illegal area style index (ERR=279)
The specified area style index is less than or equal to zero.
User action:Specify a valid area style index greater than zero.
ILLSWIUSA, Illegal switch usage (ERR=67)
The program attempts an illegal SYS call.
User action: See the appropriate RSTS/E SYS call documentation.
ILLSYSUSA, Illegal SYS usage( ) (ERR=18)
The program attempted an illegal SYS call.
User action: See the appropriate RSTS/E SYS call documentation.
ILLTEXHEI, Illegal text height (ERR=278)
The text height is less than or equal to zero.
User action:Specify a text height greater than zero.
ILLTEXJUS, Illegal text justification (ERR=263)
The specified text justification factor is invalid.
User action:See Programming with VAX BASIC Graphics for valid justification values. Specify valid values.
ILLTEXPAT, Illegal text path (ERR=265)
The specified text path is invalid.
RIGHT (the default)
LEFT
UP
DOWN
ILLTEXPRE, Illegal text precision (ERR=264)
The specified precision string is invalid.
User action:Valid precision values are: “STROKE” for software fonts, “STRING” and “CHAR” for hardware fonts. Specify a valid string for the precision value.
ILLTEXRAT, Illegal text width-to-height ratio (ERR=276)
The specified width-to-height ratio is less than or equal to zero.
User action:Specify a width-to-height ratio greater than zero.
ILLTFFOPE, Illegal terminal-format file operation (ERR=191)
The program specifies a GETRFA function on a terminal-format file.
User action:Change the file organization when opening the file to be sequential variable.
ILLTRANUM, Illegal transformation number (ERR=257)
The specified transformation number is less than 1 or greater than 255.
User action:Specify a transformation number from 1 to 255.
ILLUSADEV, Illegal usage for device (ERR=133)
The device specification contains illegal syntax.
The specified device does not exist on your system.
The specified device is inappropriate for the requested operation (for example, an indexed file access on magnetic tape).
User action: Supply the correct device type.
ILLWAIVAL, Illegal wait value (ERR=192)
The specified integer expression on the WAIT clause is less than zero or greater than 255.
User action:Specify an integer expression whose value is 0 through 255.
IMASQUROO, Imaginary square roots (ERR=54)
An argument to the SQR function is negative.
User action: Supply arguments to the SQR function that are greater than or equal to zero.
IMPERRHAN, improper error handling (ERR=186)
After an error has occurred, a program's error handler calls another program unit, and the called program unit executes an ON ERROR GO BACK statement before clearing the error with a RESUME statement. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: Change the program logic so that the called program clears the error condition before executing the ON ERROR GO BACK statement.
INDNOTFUL, Index not fully optimized (ERR=170)
A record was successfully written to an INDEXED file; however, the alternate key path was not optimized. This slows record access.
User action: Delete the record and rewrite it.
INTERR, Integer error (ERR=51)
The program contains an integer whose absolute value is greater than 127 in BYTE mode, 32,767 in WORD mode, 2,147,483,647 in LONG mode, or 9,223,372,036,854,775,807 in QUAD mode.
User action: Use an integer in the valid range for specified data type.
INVCHASTR, Invalid character in string (ERR=287)
The program attempts to output a string that contains an invalid character.
User action: Remove the invalid character from the string.
INVFILOPT, Invalid file options (ERR=139)
The program has specified invalid file options in the OPEN statement.
User action: Change the invalid file options.
INVKEYREF, Invalid key of reference (ERR=144)
The program attempts to perform a GET, FIND, or RESTORE on an INDEXED file using an invalid KEY, for example, an alternate KEY that does not exist for the file that was opened.
User action: Use a valid KEY in the GET, FIND, or RESTORE statement.
INVRFAFIE, Invalid RFA field (ERR=173)
During a FIND or GET by RFA, an invalid record's file address was specified.
User action: Supply a correct RFA field.
IO_CHAALR, I/O channel already open (ERR=7)
The program attempted to open a channel in a def or function while I/O was pending on that channel.
User action: Change the function so that it does not open the channel.
IO_CHANOT, I/O channel not open (ERR=9)
The program attempted to perform an I/O operation before opening the channel.
User action: Open the channel before attempting an I/O operation to it.
KEYFIEBEY, Key field beyond end of record (ERR=151)
The position given for the key field exceeds the maximum size of the record.
User action: Specify a key field within the record.
KEYLARTHA, Key larger than record (ERR=159)
The key specification exceeds the maximum record size.
User action: Reduce the size of the key specification.
KEYNOTCHA, Key not changeable (ERR=130)
An UPDATE statement attempted to change a key field that did not have CHANGES specified in the OPEN statement.
User action: Remove the changed key field in the UPDATE statement or specify CHANGES for that key field in the OPEN statement. Note that the primary key cannot be changed and that you cannot specify CHANGES when you open an existing file if the OPEN statement that created the file did not specify CHANGES.
KEYSIZTOO, Key size too large (ERR=145)
The key length on a GET or FIND is either zero or larger than the key length defined for the target record.
User action: Change the key specification in the GET or FIND statement.
KEYWAIEXH, Keyboard wait exhausted (ERR=15)
No input was received during the execution of an INPUT, LINPUT, or INPUT LINE statement that was preceded by a WAIT statement or INKEY$ timeout value.
User action: None; you must supply input within the specified time.
LINTOOLON, Line too long (ERR=47)
The program attempted to input more data than the input buffer can hold. The default input buffer size for terminal input is 132.
User action: Either decrease the amount of data entered at one time, or increase the size of the input buffer. You can explicitly OPEN the input device and specify the input buffer size with the RECORDSIZE or MAP clause.
MATDIMERR, Matrix dimension error (ERR=124)
Assign more than two dimensions to an array.
Reference an array with fewer or more subscripts than there are dimensions in the array.
Redimension an array that cannot be redimensioned.
Perform a matrix operation with an array that has a lower bound, other than zero, in any of its dimensions.
This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: Change the number of array subscripts. Reference the array using the correct number of dimensions, change the array so that it can be redimensioned, or change the array so that its lower bounds are zero in all of its dimensions.
MAXMEMEXC, Maximum memory exceeded (ERR=126)
The program has insufficient string and I/O buffer space because: 1) its allowable memory size has been exceeded, or 2) the system's maximum memory capacity has been reached. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: Reduce the amount of string or I/O buffer space, or split the program into two or more programs.
MEMMANVIO, Memory management violation (ERR=35)
The program attempted to read or write to a memory location to which it was not allowed access. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: If the program was compiled with /NOCHECK, it may be exceeding an array bound; recompile with /CHECK. Otherwise, check program logic.
MISSPEFEA, Missing special feature (ERR=66)
The program attempts to use an unavailable SYS call.
User action: See the appropriate RSTS/E SYS call documentation.
MOVOVEBUF, Move overflows buffer (ERR=161)
In a MOVE statement, the combined length of elements in the I/O list exceeds the size of the record just read or the size of the buffer.
User action: Reduce the size of the I/O list or increase the file's RECORDSIZE.
NEGFILSTR, Negative fill or string length (ERR=166)
A MOVE statement I/O list contains a FILL item or string length with a negative value.
User action: Change the FILL item or string length value to be greater than or equal to zero.
NEGZERTAB, negative or zero TAB (ERR=176)
The program attempted a zero or negative TAB. This error is signaled only for programs compiled with the /ANSI_STANDARD qualifier.
User action: Change the argument to the TAB statement.
NETOPERR, network operation error (ERR=182)
The program attempts to perform an invalid network operation, or the network software failed during a network operation.
User action: Take action based on the associated error messages.
NODNAMERR, Node name error (ERR=175)
A file specification's node name contains a syntax error.
User action: Supply a valid node name.
NOTBASIC, Not a BASIC error (ERR=194)
The error is not a VSI BASIC for OpenVMS error and is not mapped to an alternative VSI BASIC for OpenVMS error message.
User action:Use RMSSTATUS or VMSSTATUS to access the text of the error message.
NOTENDFIL, Not at end of file (ERR=149)
The program attempted a PUT operation: 1) on a sequential or relative file before the last record, or 2) without opening the file for WRITE access.
User action: OPEN a sequential or relative file with ACCESS APPEND or OPEN the file with ACCESS WRITE.
NOTENOAVA, Not enough available memory (ERR=111)
The program has exhausted its virtual space limits.
User action: Raise the user PGFLQUOTA limit.
NOTENODAT, Not enough data in record (ERR=59)
An INPUT statement did not find enough data in one line to satisfy all the specified variables.
User action: Supply enough data in the record or reduce the number of specified variables.
NOTIMP, Not implemented (ERR=250)
The program attempted to use a feature that does not exist in this version of VSI BASIC for OpenVMS, for example, TIME(4%).
User action: Do not use the feature.
NOTRANACC, Not a random access device (ERR=64)
The program attempts a random access on a device that does not allow such access, for example, a PUT with a record number to a magtape file.
User action: Make the access sequential instead of random or use a suitable I/O device.
NO_CURREC, No current record (ERR=131)
The program attempts a DELETE or UPDATE when the previous GET or FIND failed, or no previous GET or FIND was done.
User action: Correct the cause of failure for the previous GET or FIND, or make sure a GET or FIND was done, then retry the operation.
NO_PRIKEY, No primary key specified (ERR=150)
The program attempts to create an INDEXED file without specifying a PRIMARY KEY value.
User action: Specify a PRIMARY KEY.
NO_ROOUSE, No room for user on device (ERR=4)
No user storage space exists on the specified device.
User action: Delete files that are no longer needed.
NUMCOOINS, Number of coordinates insufficient (ERR=281)
Insufficient coordinates are provided. A GRAPH POINTS statement requires the coordinates for at least one point. A GRAPH LINES statement requires a minimum of two points. A GRAPH AREA statement requires a minimum of three points.
User action:Supply an adequate number of points.
ONEOR_TWO, One or two dimensions only (ERR=102)
The program contains a MAT statement that attempts to assign more than two dimensions to an array. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: Change the number of dimensions in the MAT statement to one or two.
ON_STAOUT, ON statement out of range (ERR=58)
The index value in an ON GOTO or ON GOSUB statement is less than one or greater than the number of line numbers in the list.
User action: Check program logic to make sure that the index value is greater than or equal to one, and less than or equal to the number of line numbers in the ON GOTO or ON GOSUB statement.
OUTOF_DAT, Out of data (ERR=57)
A READ statement requested additional data from an exhausted DATA list.
User action: Remove the READ statement, reduce the number of variables in the READ statement, or supply more DATA items.
PRIKEYOUT, Primary key out of sequence (ERR=158)
RMS has detected an error in a sequential PUT to an INDEXED file.
User action: Change the PUT statement. If this does not work, the file is corrupted and you cannot do anything.
PRIUSIFOR, PRINT-USING format error (ERR=116)
The program contains a PRINT USING statement with an invalid format string.
User action: Change the PRINT USING format string.
PROC_TRA, Programmable ^C trap (ERR=28)
A CTRL/C was typed at the controlling terminal.
User action: None; however, you can trap this error with an error handler.
PROLOSSOR, Internal error in BASIC Run-Time Library. Please submit an SPR. (ERR=103)
A consistency check in the VSI BASIC for OpenVMS run-time support failed. Program execution is aborted. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: This error should never occur. Submit a Software Performance Report.
PROVIO, Protection violation (ERR=10)
The program attempted to read or write to a file whose protection code did not allow the operation.
User action: Use a different file or change the file's protection code or the attempted operation.
RECALREXI, Record already exists (ERR=153)
An attempted random access PUT on a relative file has encountered a pre-existing record.
User action: Specify a different record number for the PUT or delete the record.
RECATTNOT, Record attributes not matched (ERR=228)
A RECORDTYPE clause specifies record attributes that do not match those of the file.
User action: Change the RECORDTYPE attribute to match that of the file.
RECBUCLOC, Record/bucket locked (ERR=154)
The program attempts to access a record or bucket that has been locked by another program.
User action: Retry the operation.
RECFILTOO, Record on file too big (ERR=157)
The specified record is longer than the input buffer.
User action: Increase the input buffer's size.
RECHASBEE, Record has been deleted (ERR=132)
A record previously located by its Record File Address (RFA) has been deleted.
User action: None.
RECNOTFOU, Record not found (ERR=155)
A random access GET or FIND was attempted on a deleted or nonexistent record.
User action: None.
RECNUMEXC, RECORD number exceeds maximum (ERR=147)
The specified record number exceeds the maximum specified for this file.
User action: Reduce the specified record number. The maximum record number cannot be specified in VSI BASIC for OpenVMS; it is either a default, or it was specified by a non-BASIC program when the file was created.
RECOVEMAP, RECORDSIZE overflows MAP buffer (ERR=185)
The OPEN statement specifies a RECORDSIZE value larger than the size of the MAP specified in the MAP clause. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: Increase the size of the MAP to match the RECORDSIZE value.
REDARR, Redimensioned array (ERR=105)
A MAT statement attempts to redimension an array to have more elements than were originally dimensioned.
User action: Change the statement that attempts the redimension or increase the original number elements.
REMOVEBUF, REMAP overflows buffer (ERR=183)
A REMAP statement causes the variables in the dynamic MAP to be associated with nonexistent storage.
User action: Change the REMAP statement so that all variables are associated with the storage in the MAP.
REMSTRNOT, REMAP string is not static (ERR=196)
The program referenced a string with a REMAP statement that was not declared in COMMON or MAP.
User action: Declare the string in the COMMON or MAP statement.
RESNO_ERR, RESUME and no error (ERR=104)
The program executes a RESUME statement without a line number outside of the error handling routine. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: Check program logic to make sure that the RESUME statement is executed only in the error handler.
RETWITGOS, RETURN without GOSUB (ERR=72)
The program executes a RETURN statement before a GOSUB. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: Check program logic to make sure that RETURN statements are executed only in subroutines or remove the RETURN statement.
RRVNOTFUL, RRV not fully updated, (ERR=171)
RMS wrote a record successfully, but did not update one or more Record Retrieval Vectors; therefore, you cannot retrieve any records associated with those vectors.
User action: Delete the record and rewrite it.
SCAFACINT, SCALE factor interlock (ERR=127)
A subprogram was compiled with a different SCALE factor than that of the calling program. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: Recompile one of the programs with a scale factor that matches the other.
SIZRECINV, Size of record invalid (ERR=156)
COUNT equals zero.
COUNT exceeds the maximum size of the record.
COUNT conflicts with the actual size of the current record during a sequential file UPDATE on disk.
COUNT does not equal the record size for fixed format records.
You specified a record size in the OPEN statement that was unequal to the actual record size established when the file was created.
User action: Supply a valid COUNT value in the PUT or UPDATE statement, or a valid RECORDSIZE in the OPEN statement, whichever is applicable.
STO, Stop (ERR=123)
The program executed a STOP statement. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = INFO or a greater severity.
User action: Continue execution by typing CONTINUE or terminate execution by typing EXIT.
STRLENZER, string length is zero (ERR=288)
A graphics statement references a null string where a null string is illegal.
User action: Adjust the string length so that it is greater than zero.
STRTOOLON, String too long (ERR=227)
The program attempts to create a string longer than 65,535 bytes.
User action: Reduce the length of the string.
SUBOUTRAN, Subscript out of range (ERR=55)
The program attempts to reference an array element outside of the array's dimensioned bounds.
User action: Check program logic to make sure that all array references are to elements within the array boundaries.
TAPBOTDET, Tape BOT detected (ERR=129)
The program attempts a rewind or backspace operation on a magnetic tape that is already at the beginning of the file.
User action: Trap the error or check program logic; do not rewind or backspace if the magnetic tape is at the beginning of the file.
TAPNOTANS, Tape not ANSI labeled (ERR=146)
The program attempts to access a file-structured magnetic tape that does not have an ANSI label.
User action: Determine the magnetic tape's format by mounting it with the /FOREIGN qualifier and using the DCL DUMP command. You can then access it as a non-file-structured magnetic tape.
TAPRECNOT, Tape records not ANSI (ERR=128)
The records in the magtape you accessed are neither ANSI D nor ANSI F format.
User action: Determine the magtape's format by mounting it with the /FOREIGN qualifier and using the DCL DUMP command.
TERFORFIL, Terminal format file required (ERR=164)
The program attempted to use PRINT #, INPUT #, LINPUT #, MAT INPUT #, MAT PRINT #, or PRINT USING # to access a RELATIVE, INDEXED, or VIRTUAL file.
User action: Supply a terminal-format file.
TOOFEWARG, Too few arguments (ERR=97)
A function invocation, CALL, or DRAW statement passed fewer arguments than were defined in the function, picture, DEF, DEF*, or subprogram. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: Change the number of arguments to match the number defined in the function or subprogram.
TOOLITDAT, too little data in record (ERR=189)
An INPUT statement did not find enough data in one line to satisfy all the specified variables. This error is signaled only for programs compiled with the /ANSI_STANDARD qualifier.
User action: Supply enough data in the record, or reduce the number of specified variables.
TOOMANARG, Too many arguments (ERR=89)
A function invocation, CALL, or DRAW statement passed more arguments than were expected. This error cannot be trapped with a VSI BASIC for OpenVMS error handler unless the program contains OPTION HANDLE = SEVERE.
User action: Reduce the number of arguments. A SUB or FUNCTION subprogram can pass a maximum of 255 arguments; a DEF function call can pass a maximum of eight arguments.
TOOMUCDAT, too much data in record (ERR=177)
The user has given too many items in response to the INPUT statement. This error is only signaled for ANSI INPUT.
User action: Supply the correct number of items to the INPUT statement or change the INPUT statement.
TRANOTDIF, Transformation numbers are not different (ERR=260)
The same transformation number is used twice in the SET INPUT PRIORITY statement.
User action:Specify two different transformations in the SET INPUT PRIORITY statement.
UNEFILDAT, unexpired file date (ERR=179)
The program attempts to delete a file whose expiration date has not yet passed.
User action: None.
UNINUMNOT, Unit number is not defined for the device (ERR=282)
The specified unit is a method that is not supported by the device. (The default unit is 1.)
User action:Verify the supported units for the device and specify a valid unit.
UNKGKSERR, Unknown DEC GKS FOR VMS error (ERR=286)
A graphics error has occurred that is not mapped to a VSI BASIC for OpenVMS error message.
User action:Use VMSSTATUS to access the text of the Compaq GKS error message.
USEABOINP, User aborted input, locate point cancelled (ERR=293)
The middle mouse button was pressed during the execution of a graphics input statement that uses a mouse to enter points (for example, LOCATE POINT). The pressing of the middle mouse button aborts the graphics input statement in progress and the data in the variables used for the graphics input statement is unchanged.
The pressing of the middle mouse button during a graphics input statement is analogous to typing Ctrl/Z at a regular INPUT statement.
User action: None. The program can trap this error in an error handler and attempt the input statement again if so desired.
VIRARRDIS, Virtual array not on disk (ERR=43)
The program attempted to reference a virtual array on a nondisk device, or the virtual array is not opened as ORGANIZATION VIRTUAL.
User action: Virtual arrays must be on disk; change the file specification in the OPEN statement for this array. Open the file with ORGANIZATION VIRTUAL.
VIRARROPE, Virtual array not yet open (ERR=45)
The program attempted to reference a virtual array before opening the associated disk file.
User action: Open the disk file containing the virtual array before referencing the array.
VIRBUFTOO, Virtual buffer too large (ERR=42)
The program attempted to access a VIRTUAL file and the buffer size was not 512 bytes.
User action: Change the I/O buffer to be a multiple of 512 bytes.
B.2. VSI BASIC for OpenVMS Run-Time Errors by Number
Error Number |
Explanation |
---|---|
1 |
BADDIRDEV, Bad directory for device |
2 |
ILLFILNAM, Illegal file name |
4 |
NO_ROOUSE, No room for user on device |
5 |
CANFINFIL, Can't find file or account |
7 |
IO_CHAALR, I/O channel already open |
9 |
IO_CHANOT, I/O channel not open |
10 |
PROVIO, Protection violation |
11 |
ENDFILDEV, End of file on device |
12 |
FATSYSIO_, Fatal system I/O failure |
14 |
DEVHUNWRI, Device hung or write locked |
15 |
KEYWAIEXH, Keyboard wait exhausted |
18 |
ILLSYSUSA, Illegal SYS( ) usage |
28 |
PROC__TRA, Programmable ^C trap |
29 |
CORFILSTR, Corrupted file structure |
31 |
ILLBYTCOU, Illegal byte count for I/O |
35 |
MEMMANVIO, Memory management violation |
42 |
VIRBUFTOO, Virtual buffer too large |
43 |
VIRARRDIS, Virtual array not on disk |
45 |
VIRARROPE, Virtual array not yet open |
46 |
ILLIO_CHA, Illegal I/O channel |
47 |
LINTOOLON, Line too long |
48 |
FLOPOIERR, Floating point error or overflow |
49 |
ARGTOOLAR, Argument too large in EXP |
50 |
DATFORERR, Data format error |
51 |
INTERR, Integer error |
52 |
ILLNUM, Illegal number |
53 |
ILLARGLOG, Illegal argument in LOG |
54 |
IMASQUROO, Imaginary square roots |
55 |
SUBOUTRAN, Subscript out of range |
56 |
CANINVMAT, Can't invert matrix |
57 |
OUTOF_DAT, Out of data |
58 |
ON_STAOUT, ON statement out of range |
59 |
NOTENODAT, Not enough data in record |
61 |
DIVBY_ZER, Division by 0 |
63 |
FIEOVEBUF, FIELD overflows buffer |
64 |
NOTRANACC, Not a random access device |
66 |
MISSPEFEA, Missing special feature |
67 |
ILLSWIUSA, Illegal switch usage |
72 |
RETWITGOS, RETURN without GOSUB |
73 |
FNEWITFUN, FNEND without function call |
88 |
ARGDONMAT, Arguments don't match |
89 |
TOOMANARG, Too many arguments |
97 |
TOOFEWARG, Too few arguments |
101 |
DATTYPERR, Data type error |
102 |
ONEOR_TWO, One or two dimensions only |
103 |
PROLOSSOR, Internal error in BASIC Run-Time Library. Please submit an SPR. |
104 |
RESNO_ERR, RESUME and no error |
105 |
REDARR, Redimensioned array |
116 |
PRIUSIFOR, PRINT-USING format error |
122 |
ILLFIEVAR, Illegal FIELD variable |
123 |
STO, Stop |
124 |
MATDIMERR, Matrix dimension error |
126 |
MAXMEMEXC, Maximum memory exceeded |
127 |
SCAFACINT, SCALE factor interlock |
128 |
TAPRECNOT, Tape records not ANSI |
129 |
TAPBOTDET, Tape BOT detected |
130 |
KEYNOTCHA, Key not changeable |
131 |
NO_CURREC, No current record |
132 |
RECHASBEE, Record has been deleted |
133 |
ILLUSADEV, Illegal usage for device |
134 |
DUPKEYDET, Duplicate key detected |
136 |
ILLILLACC, Illegal or illogical access |
137 |
ILLKEYATT, Illegal key attributes |
138 |
FILIS_LOC, File is locked |
139 |
INVFILOPT, Invalid file options |
141 |
ILLOPE, Illegal operation |
142 |
ILLRECFIL, Illegal record on file |
143 |
BADRECIDE, Bad record identifier |
144 |
INVKEYREF, Invalid key of reference |
145 |
KEYSIZTOO, Key size too large |
146 |
TAPNOTANS, Tape not ANSI labelled |
147 |
RECNUMEXC, RECORD number exceeds maximum |
148 |
BADRECVAL, Bad RECORDSIZE value on OPEN |
149 |
NOTENDFIL, Not at end of file |
150 |
NO_PRIKEY, No primary key specified |
151 |
KEYFIEBEY, Key field beyond end of record |
152 |
ILLRECACC, Illogical record accessing |
153 |
RECALREXI, Record already exists |
154 |
RECBUCLOC, Record/bucket locked |
155 |
RECNOTFOU, Record not found |
156 |
SIZRECINV, Size of record invalid |
157 |
RECFILTOO, Record on file too big |
158 |
PRIKEYOUT, Primary key out of sequence |
159 |
KEYLARTHA, Key larger than record |
160 |
FILATTNOT, File attributes not matched |
161 |
MOVOVEBUF, Move overflows buffer |
162 |
CANNOT OPEN FILE |
164 |
TERFORFIL, Terminal format file required |
166 |
NEGFILSTR, Negative fill or string length |
168 |
ILLALLCLA, Illegal ALLOW clause |
170 |
INDNOTFUL, Index not fully optimized |
171 |
RRVNOTFUL, RRV not fully updated, |
173 |
INVRFAFIE, Invalid RFA field |
174 |
FILEXPDAT, File expiration date not yet reached |
175 |
NODNAMERR, Node name error |
176 |
NEGTABNOT, Negative TAB not allowed |
177 |
TOOMUCDAT, Too much data in record |
178 |
ERRFILCOR, Error on OPEN - file corrupted |
179 |
UNEFILDAT, Unexpired file date |
181 |
DECERR, Decimal error or overflow |
182 |
NETOPERR, Network operation error |
183 |
REMOVEBUF, REMAP overflows buffer |
185 |
RECOVEMAP, RECORDSIZE overflows MAP buffer |
186 |
IMPERRHAN, Improper error handling |
187 |
ILLRECLOC, Illegal record locking |
189 |
TOOLITDAT, Too little data in record |
190 |
ILLNETOPE, Illegal network operation |
191 |
ILLTFFOPE, Illegal terminal-format file operation |
192 |
ILLWAIVAL, Illegal wait value |
193 |
DEADLOCK, Detected deadlock while waiting for GET or FIND |
194 |
NOTBASIC, Not a BASIC error |
195 |
DIMOUTRAN, Dimension number out of range |
196 |
REMSTRNOT, REMAP string is not static |
197 |
ARRTOOSMA, Array too small |
226 |
GKSNOTINS, DEC GKS FOR VMS is not installed |
227 |
STRTOOLON, String too long |
228 |
RECATTNOT, Record attributes not matched |
229 |
DIFUSELON, Differing use of LONG/WORD qualifiers |
238 |
ARRMUSSAM, Arrays must be same dimension |
239 |
ARRMUSSQU, Arrays must be square |
240 |
CANCHAARR, Cannot change array dimensions |
245 |
ILLEXIDEF, Illegal exit from DEF* |
246 |
ERRTRANEE, ERROR trap needs RESUME |
247 |
ILLRESSUB, Illegal RESUME to subroutine |
250 |
NOTIMP, Not implemented |
252 |
FILACPFAI, FILE ACP failure |
253 |
DIRERR, Directive error |
256 |
ECHTYPNOT, Prompt/echo type not supported |
257 |
ILLTRANUM, Illegal transformation number |
258 |
ILLPICOPE, Illegal picture operation |
259 |
CLIPONOFF, Clipping must be ON or OFF |
260 |
TRANOTDIF, Transformation numbers are not different |
261 |
COLNOTCON, Color indices are not contiguous |
262 |
ILLARESTY, Illegal area style |
263 |
ILLTEXJUS, Illegal text justification |
264 |
ILLTEXPRE, Illegal text precision |
265 |
ILLTEXPAT, Illegal text path |
266 |
ILLDEVID, Illegal device identification number |
267 |
DEVTYPNOT, Device type is not supported |
268 |
DEVNOTOPE, Device is not open |
269 |
DEVOUTMET, Device is an output metafile |
270 |
DEVINMET, Device is an input metafile |
272 |
DEVOPEING, Device and operation are incompatible |
273 |
COONOTNDC, Coordinates are not within NDC space |
274 |
ILLLINSTY, Illegal line style number |
275 |
ILLLINSIZ, Illegal line size |
276 |
ILLPOISTY, Illegal point style number |
277 |
ILLTEXRAT, Illegal text width-to-height ratio |
278 |
ILLTEXHEI, Illegal text height |
279 |
ILLSTYIND, Illegal area style index |
280 |
ILLCOLIND, Illegal color index |
281 |
NUMCOOINS, Number of coordinates is insufficient |
282 |
UNINUMNOT, Unit number is not defined for the device |
283 |
ILLECHARE, Illegal echo area |
284 |
ILLINIVAL, Illegal initial value |
285 |
ENTPOINOT, Entered points not within a transformation |
286 |
UNKGKSERR, Unknown DEC GKS FOR VMS error |
287 |
INVCHASTR, Invalid character in string |
288 |
STRLENZER, String length is zero |
289 |
DATOVERF, Data overflow |
290 |
ILLCNTCLA, Illegal count clause |
291 |
ILLCOLMIX, Illegal color mix |
292 |
ILLDEVNAM, Illegal device name in OPEN |
293 |
USEABOINP, User aborted input, locate point cancelled |
B.3. Errors Not Generated by VSI BASIC for OpenVMS
Number |
Text |
---|---|
3 |
?Account or device in use |
6 |
?Not a valid device |
8 |
?Device not available |
13 |
?User data error on device |
16 |
?Name or account now exists |
17 |
?Too many open files on unit |
19 |
?Disk block is interlocked |
20 |
?Pack ids don't match |
21 |
?Disk pack is not mounted |
22 |
?Disk pack is locked out |
23 |
?Illegal cluster size |
24 |
?Disk pack is private |
25 |
?Disk pack needs ’cleaning ’ |
26 |
?Fatal disk pack mount error |
27 |
?I/O to detached keyboard |
30 |
?Device not file-structured |
32 |
?No buffer space available |
33 |
?Odd address trap |
34 |
?Reserved instruction trap |
36 |
?SP stack overflow |
37 |
?Disk error during swap |
38 |
?Memory parity (or ECC) failure |
39 |
?Magtape select error |
40 |
?Magtape record length error |
41 |
?Non-res run-time system |
44 |
?Matrix or array too big |
47 |
?Line too long |
60 |
?Integer overflow, FOR loop |
62 |
?No run-time system |
65 |
?Illegal MAGTAPE( ) usage |
68-70 |
unused |
71 |
?Statement not found |
74 |
?Undefined function called |
75 |
?Illegal symbol |
76 |
?Illegal verb |
77 |
?Illegal expression |
78 |
?Illegal mode mixing |
79 |
?Illegal IF statement |
80 |
?Illegal conditional clause |
81 |
?Illegal function name |
82 |
?Illegal dummy variable |
83 |
?Illegal FN redefinition |
84 |
?Illegal line number(s) |
85 |
?Modifier error |
86 |
?Can't compile statement |
87 |
?Expression too complicated |
90 |
%Inconsistent function usage |
91 |
?Illegal DEF nesting |
92 |
?FOR without NEXT |
93 |
?NEXT without FOR |
94 |
?DEF without FNEND |
95 |
?FNEND without DEF |
96 |
?Literal string needed |
98 |
?Syntax error |
99 |
?String is needed |
100 |
?Number is needed |
106 |
%Inconsistent subscript use |
107 |
?ON statement needs GOTO |
108 |
?End of statement not seen |
109 |
?What? |
110 |
?Bad line number pair |
111 |
?Not enough available memory |
112 |
?Execute only file |
113 |
?Please use the run command |
114 |
?Can't CONTinue |
115 |
?File exists-RENAME/REPLACE |
117 |
?Matrix or array without DIM |
118 |
?Bad number in PRINT USING |
119 |
?Illegal in immediate mode |
120 |
?PRINT-USING buffer overflow |
121 |
?Illegal statement |
125 |
?Wrong math package |
135 |
?Illegal usage |
140 |
?Index not initialized |
163 |
?No file name |
165 |
?Cannot position to EOF |
167 |
?Illegal record format |
169 |
unused |
172 |
?Record lock failed |
180 |
?No support for operation in task |
182 |
?Network operation rejected |
184 |
?Unaligned REMAP variable |
188 |
?UNLOCK EXPLICIT requires RECORDSIZE 512 |
198-225 |
unused |
230 |
?No fields in image |
231 |
?Illegal string image |
232 |
?Null image |
233 |
?Illegal numeric image |
234 |
?Numeric image for string |
235 |
?String image for numeric |
236 |
?TIME limit exceeded |
237 |
?First arg to SEG$ greater than second |
241 |
?Floating overflow |
242 |
?Floating underflow |
243 |
?CHAIN to nonexistent line number |
244 |
?Exponentiation error |
248 |
?Illegal return from subroutine |
249 |
?Argument out of bounds |
251 |
?Recursive subroutine call |
254-255 |
unused |
294-300 |
unused |
Appendix C. Optional Programming Productivity Tools
This appendix provides an overview of optional programming productivity tools. These tools are not included with the VSI BASIC software; they must be purchased separately. Using these tools can increase your productivity as a VSI BASIC programmer.
Digital Language Sensitive Editor for OpenVMS (LSE) and Digital Source Code Analyzer for OpenVMS (SCA) (Section C.1, “Language Sensitive Editor (LSE) and Source Code Analyzer (SCA)”)
Oracle CDD/Repository (Section C.2, “CDD/Repository”)
Database Management System (DBMS) (Section C.3, “Database Management System (DBMS)”)
Digital Test Manager for OpenVMS (Section C.4, “Digital Test Manager for OpenVMS”)
Digital Code Management System for OpenVMS (CMS) (Section C.5, “Code Management System for OpenVMS (CMS)”)
For more information on using these tools, see the listed documentation at the end of each section.
For information about how to purchase these tools, contact your VSI Software, Inc.
C.1. Language Sensitive Editor (LSE) and Source Code Analyzer (SCA)
The Digital Language Sensitive Editor for OpenVMS (LSE) and the Digital Source Code Analyzer for OpenVMS (SCA) must be purchased separately. LSE is a powerful and flexible text editor designed specifically for software development. LSE has important features that help you produce syntactically correct code in VSI BASIC. SCA is an interactive tool that is used to perform program analysis.
LSE and SCA are closely integrated products; generally, SCA can be invoked through LSE. LSE provides additional editing features that make SCA program analysis more efficient. In addition, LSE and SCA, in conjunction with the VSI BASIC compiler, provide a set of new enhancements supporting source code designing and review.
For more information about LSE and SCA, see the Guide to Language-Sensitive Editor for OpenVMS Systems and Guide to Source Code Analyzer for VMS Systems.
C.1.1. Preparing an SCA Library
SCA stores data generated by the VSI BASIC compiler in an SCA library. The data in the SCA library contains information about all symbols, modules, and files encountered during a specific compilation of the source.
$
BASIC/ANALYSIS_DATA PG1,PG2,PG3
This command line compiles the input files PG1.BAS, PG2.BAS, and PG3.BAS, and generates corresponding output files for each input file with the file types OBJ and ANA. SCA puts these files in your current default directory.
$
SCA LOAD PG1,PG2,PG3
This command loads your library with the modules contained in the data analysis files PG1.ANA, PG2.ANA, and PG3.ANA.
After the SCA library has been prepared, enter LSE to begin an SCA session. Within this context, the integration of LSE and SCA provides commands that can be used only within LSE.
C.1.2. Compiling From Within LSE
LSE>
COMPILE
LSE>
COMPILE $/ANALYSIS_DATA/DESIGN=(PLACEHOLDERS, COMMENTS)
The /ANALYSIS_DATA qualifier causes the compiler to generate an analysis data file containing source code analysis information. This information is provided to the SCA library.
The /DESIGN qualifier instructs the VSI BASIC compiler to recognize placeholders and design comments as valid program elements. If the /ANALYSIS_DATA qualifier has also been specified, the VSI BASIC compiler includes information on placeholders and design comments in the analysis data file.
C.1.3. VSI BASIC Support for LSE and SCA Features
This section describes information specific to BASIC for programming language placeholders and tokens.
LSE accepts keywords, or tokens, for all languages with LSE support. However, the specific tokens themselves are language defined. For example, you can expand the [MAT] token only when using VSI BASIC.
Note
Keywords such as TYPE, VARIANT, IF, FOR, and OPEN, can be tokens as well as placeholders. Therefore, any time you are in LSE with the language set to VSI BASIC, you can type one of these words and press Ctrl/E to expand the construct.
Remember that braces ({}) enclose required placeholders and brackets ([]) enclose optional placeholders. Note that when you erase an optional placeholder, LSE also deletes any associated text before and after that placeholder.
LSE> SHOW TOKEN IF {lists the token IF} LSE> SHOW TOKEN {lists all tokens}
LSE> GOTO BUFFER $SHOW
LSE> WRITE filename.filetype
You can use the PRINT command to print the file you created.
C.2. CDD/Repository
VSI BASIC supports CDD/Repository. The current version of CDD/Repository is compatible with previous versions of CDD.
See Chapter 21, Using CDD/Repository with BASIC for more information about CDD/Repository.
C.3. Database Management System (DBMS)
DBMS is a multiuser, general-purpose, CODASYL-compliant database management system. DBMS is used for accessing and administrating databases ranging in complexity from simple hierarchies to complex networks with multilevel relationships. DBMS supports full concurrent access in a multiuser environment without compromising the integrity and security of your database.
For more information, see the DBMS documentation.
C.4. Digital Test Manager for OpenVMS
The Test Manager helps test software during development and maintenance. This tool automates the organization, execution, and review of tests and allows several developers to use one set of tests at the same time.
With the Test Manager, you can describe your tests, organize them by assigning them to groups, and choose combinations of tests to run by test name or by group. The Test Manager executes the tests selected and then compares the result with the expected results.
For more information, see the Guide to Test Manager for VMS Systems.
C.5. Code Management System for OpenVMS (CMS)
The Code Management System for OpenVMS (CMS) is a program librarian for software development and evolution. It is comprised of a set of commands that enable you to manage files of an ongoing project.
For more information about CMS, see the Guide to Source Code Analyzer for VMS Systems.
Unless the subroutine is compiled with the /NOSETUP qualifier or equivalent, it will appear to step into RTL code, because an environment setup RTL routine is normally called as the very first thing of the subroutine.
The SET NO PROMPT statement turns off the optional question mark; see Section 5.1.1.3, “Enabling and Disabling the Question Mark Prompt”.
Terminal I/O statements include INPUT, INPUT LINE, LINPUT, MAT INPUT, and so on.
Record File Addresses do not exist for terminal-format files.
Specifies the default parameter-passing mechanism.
Use the LOC function to pass the address of an AST routine to a system service. Specify BY VALUE for the passing mechanism.
Although unsigned data structures are not directly supported in BASIC, you can substitute the signed equivalent provided you do not exceed the range of the signed data structure.
The definition of the RECORD structures are included in the VSI BASIC for OpenVMS system definitions text library. See Section 19.4.4, “Including Symbolic Definitions” for more information.
CDD/Repository specifies bit field length in bits; VSI BASIC for OpenVMS
specifies string length in bytes. If the length in bits
does not divide evenly into bytes, VSI BASIC for OpenVMS signals the
error “Field <fieldname>
from CDD/Repository has bit offset or
length.”
VSI BASIC does not support the H_floating or HFLOAT data type.