# Compaq BASIC for OpenVMS
Alpha and VAX Systems
User Manual

Previous | Contents | Index

### 15.3.3.8 Debits and Credits

You can have BASIC use credit and debit notation to differentiate positive and negative numbers. To do this, you place the characters <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.

# 15.4 Printing Strings

With the PRINT USING statement, you can specify the following aspects of string format:

- The number of characters
- Left-justified format
- Right-justified format
- Centered format
- Extended field format

Table 15-2 summarizes the format characters and their effects.

Table 15-2 Format Characters for String Fields
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.

You must start string format fields with a single quotation mark (') that reserves a space in the print field, followed by:

- 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 15.4.4.

A string field containing only a single quotation mark is a 1-character string field. BASIC prints the first character of the string expression corresponding to a 1-character string field and ignores all following characters.

    PRINT USING "'","ABCDE"
    END

Output

    A

See Section 15.4.4 for an example of different types of fields used together.

## 15.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.

A left-justified field contains a single quotation mark followed by a series of Ls.

    PRINT USING "'LLLLLL","ABCDE"
    PRINT USING "'LLLL","ABC"
    PRINT USING "'LLLLL","12345678"
    END

Output

    ABCDE
    ABC
    123456

## 15.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.

A right-justified field contains a single quotation mark (') followed by a series of Rs.

    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

## 15.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.

A centered field contains a single quotation mark followed by a series of Cs.

    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"
    END

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.

## 15.4.4 Extended Fields

An extended field contains a single quotation mark followed by one or more Es. The extended field is the only field that automatically prints the entire string. In addition:

- 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

The following example uses left-justified, right-justified, centered, and extended fields:

    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

# 15.5 PRINT USING Statement Error Conditions

There are two types of PRINT USING error conditions: fatal and warning. BASIC signals a fatal error if:

- 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 16
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 BASIC 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.

# 16.1 Default Error Handling

BASIC 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, BASIC diagnoses the error and displays a message telling you the nature and severity of the error. There are four severity levels of BASIC 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 BASIC 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 BASIC error handler when an error occurs. For example, when BASIC 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.

# 16.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.

Example 1

    WHEN ERROR IN
         protected_statement_1
         protected_statement_2
         .
         .
         .
     USE
         handler_statement_1
         handler_statement_2
         .
         .
         .
    END WHEN

Example 2

    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.

## 16.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 16.2.3 and Section 16.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.

The following example prompts the user for two integer values and displays their sum. The WHEN ERROR block traps any invalid input values, displays a message telling the user that the input was invalid, and reprompts the user for input.

    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.

## 16.2.2 Handlers

A handler is the block of code containing instructions to be executed only when an error occurs during the execution of statements in the protected region. When an error occurs during the execution of a protected region, BASIC branches to the handler you have supplied. In turn, the handler processes the error. An error handler typically performs the following functions:

- 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.

An attached handler is delimited by a USE and an END WHEN statement. The attached handler immediately follows the protected region of a WHEN ERROR IN block. The following example shows an attached handler that traps errors on I/O statements, division by zero, and illegal numbers:

    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

A detached handler is defined separately in your program unit. It requires an identifier and must be delimited by a HANDLER and an END HANDLER statement. Handler names must be valid BASIC identifiers and cannot be the same as the identifier for any label, PROGRAM name, DEF or DEF* function, SUB, FUNCTION, or PICTURE subprogram. The main advantage of using a detached handler is that it can be referenced by more than one WHEN ERROR USE statement. The following example shows a simple detached handler:

     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 BASIC 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.

Your handler can include conditional expressions to test the error and branch accordingly, as shown in the following example:

    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 16.3.

Previous | Next | Contents | Index