ILE RPG Programmer's Guide


Avoiding a Loop in an Error Subroutine

In the previous example, it is unlikely that an error would occur in the *PSSR and thereby cause a loop. However, depending on how the *PSSR is written, loops may occur if an exception occurs while processing the *PSSR.

One way to avoid such a loop is to set a first-time switch in the subroutine. If it is not the first time through the subroutine, you can specify an appropriate return point, such as *CANCL, for the Factor 2 entry of the ENDSR operation.

Figure 142 shows a program NOLOOP which is designed to generate exceptions in order to show how to avoid looping within a *PSSR subroutine. The program generates an exception twice:

  1. In the main body of the code, to pass control to the *PSSR
  2. Inside the *PSSR to potentially cause a loop.
Figure 142. Avoiding a Loop in an Error Subroutine
      *=================================================================*
      * NOLOOP:  Show how to avoid recursion in a *PSSR subroutine.     *
      *=================================================================*
      *-----------------------------------------------------------------*
      * Array that will be used to cause an error                       *
      *-----------------------------------------------------------------*
     D Arr1            S             10A   DIM(5)
      *-----------------------------------------------------------------*
      * Generate an array out of bounds error to pass control to *PSSR. *
      *-----------------------------------------------------------------*
     C                   Z-ADD     -1            Neg1              5 0
     C                   MOVE      Arr1(Neg1)    Arr1(Neg1)
     C                   MOVE      *ON           *INLR
      *=================================================================*
      * *PSSR: Error Subroutine for the procedure.  We use the          *
      *        variable InPssr to detect recursion in the PSSR.         *
      *        If we detect recursion, then we *CANCL the procedure.    *
      *=================================================================*
     C     *PSSR         BEGSR
     C                   IF        InPssr = 1
     C                   MOVE      '*CANCL'      ReturnPt          6
     C                   Z-ADD     0             InPssr            1 0
     C                   ELSE
     C                   Z-ADD     1             InPssr
      *                                                                 *
      *         We now generate another error in the PSSR to see        *
      *         how the subroutine cancels the procedure.               *
      *                                                                 *
     C                   MOVE      Arr1(Neg1)    Arr1(Neg1)
      *                                                                 *
      *         Note that the next two operations will not be           *
      *         processed if Neg1 is still negative.                    *
      *                                                                 *
     C                   MOVE      '*GETIN'      ReturnPt
     C                   Z-ADD     0             InPssr
     C                   ENDIF
     C                   ENDSR     ReturnPt

To create the program and start debugging it, using the source in Figure 142, type:

CRTBNDRPG PGM(MYLIB/NOLOOP) DBGVIEW(*SOURCE)
STRDBG PGM(MYLIB/NOLOOP)

Set a break point on the BEGSR line of the *PSSR subroutine so you can step through the *PSSR subroutine.

When you call the program, the following occurs:

  1. An exception occurs when the program tries to do a MOVE operation on an array using a negative index. Control is passed to the *PSSR.
  2. Since this is the first time through the *PSSR, the variable In_Pssr is not already set on. To prevent a future loop, the variable In_Pssr is set on.
  3. Processing continues within the *PSSR with the MOVE after the ELSE. Again, an exception occurs and so processing of the *PSSR begins anew.
  4. This time through, the variable In_Pssr is already set to 1. Since this indicates that the subroutine is in a loop, the procedure is canceled by setting the ReturnPt field to *CANCL.
  5. The ENDSR operation receives control, and the procedure is canceled.

The approach used here to avoid looping can also be used within an INFSR error subroutine.


[ Top of Page | Previous Page | Next Page | Contents | Index ]