5 Error and message reporting

As mentioned previously, ADAM programs should not normally use Fortran WRITE (nor indeed READ) statements5. This is because using these would subvert the sophisticated way in which ADAM performs I/O.

Two sets of subroutine libraries are available to output messages; these are the MSG_ and ERR_ routines, with the latter reserved for error reports (see SUN/104 for a full description). The ADAM ALINK command automatically links in these subroutine libraries.

Message Reporting.

The primary routine for reporting messages is MSG_OUT, which has the calling sequence below, where MSG is a string containing the message name, which is often blank6, TEXT is the message text, and STATUS is the global status. (The routine will not execute if STATUS is not OK.)

        CALL MSG_OUT (MSG, TEXT, STATUS)

Thus the example below would result in the message ‘HELLO’.

        CALL MSG_OUT (’ ’, ’HELLO’, STATUS)

Should the programmer wish to embed any program variables in the message, this can be accomplished with the use of tokens. A token is set to the value of the variable concerned using one of the MSG_SETx routines which have the form:

        CALL MSG_SETx (’TOKEN’, VALUE)

where ‘x’ is one of R, I, D, L or C to deal with real, integer, double precision, logical and character variables respectively. The tokens are inserted in the message text at a point indicated by ^TOKEN.

Thus, in the example program in the previous section the integer NDIM could be reported as follows:

        CALL MSG_SETI (’NDIM’, NDIM)
        CALL MSG_OUT (’ ’, ’No. of dimensions is ^NDIM’, STATUS)

The dimensions are reported separately to avoid the problem of not knowing how many there are7:

        CALL MSG_OUT (’ ’, ’Dimensions are:’, STATUS)
        DO I=1,NDIM
           CALL MSG_SETI (’DIM’, DIM(I))
           CALL MSG_OUT (’  ’, ’             ^DIM’, STATUS)
        ENDDO

These changes have been made in ADAM_EXAMPLES:REPDIM1.FOR.

Values output in this way have the most concise format possible. If the programmer wishes to use a particular format this is done by setting the token with a MSG_FMTx routine instead of MSG_SETx. The former routines have the calling sequence:

        CALL MSG_FMTx (TOKEN, FORMAT, VALUE)

For example if the variable Y=193.12, the two calls following result in the message on the last line:

        CALL MSG_FMTR (’YVAL’, ’(1E12.3)’, Y)
        CALL MSG_OUT (’ ’, ’Y value is ^YVAL’, STATUS)
  
    Y value is  0.193E+03

If an unsuitable format is used in these routines the token is not set. Generally if a token is undefined, the output message contains the token name in brackets, for example:

  Y value is ^<YVAL>

N.B. ALL message tokens become undefined after a call to MSG_OUT.

Error Reporting.

Errors are reported using ERR_REP which is of similar form to MSG_OUT and uses tokens in the same way. The calling sequence is:

        CALL ERR_REP (ERR, TEXT, STATUS)

Unlike MSG_OUT this routine will execute with bad status set, for obvious reasons. It is recommended that a meaningful non-blank error name is used.

In general, if a program reaches an error condition it should set STATUS to an error value, report the error and abort. For example the program IMADD can only deal with 2-D arrays:

        IF (NDIM.NE.2) THEN
           STATUS=SAI__ERROR
           CALL MSG_SETI (’NDIM’, NDIM)
           CALL ERR_REP (’IMADD_NOTIMAGE’,
       :        ’Array is not an image, but is ^NDIM-dimensional’, STATUS)
           GOTO 999
        ENDIF

Generally the error value in an applications program should be set to SAI__ERROR, a symbolic constant defined in the SAE_PAR file which is used to represent a general error condition8.

If STATUS is set by a subroutine, that subroutine should make an error report as described above. However the calling program may make an additional report to provide contextual information. For example:

        CALL IMADD (ARRAY, CONST, STATUS)
        IF (STATUS.NE.SAI__OK)THEN
           CALL ERR_REP (’CADD_ADD’, ’CADD: Error adding constant to array’,
       :                  STATUS)
           GOTO 999
        ENDIF

N.B. ALL message tokens become undefined after a call to ERR_REP.

Message Synchronization.

When running under ICL (see Section 17) it is sometimes important to ensure that the output of messages to the terminal has been completed before subsequent screen output takes place. Such a situation occurs when messages and graphics output are interspersed in a program – messages may be reported on the graphics rather than the text plane of a VDU; an example is discussed in Section 17. The problem is avoided by making the call below immediately before any graphical output. (Unnecessary use is harmless.)

        CALL MSG_SYNC (STATUS)

5However, Section 9 illustrates when this can be appropriate.

6If not blank, the message name should be unique within the application; this message name can be used to refer to alternative message text defined in the program interface file, but this procedure is not recommended.

7A more elegant method of formatting this message is shown in Section 11 which deals with the CHR_ character handling routines.

8Many system routines set errors to values with associated meanings for which explicit tests can be made. An example is shown in Section 9