条件処理プログラムの使用

次の例は以下のことを行う方法を示したものです。
  1. RPG「範囲外」エラーを処理する条件処理プログラムをコーディングする
  2. 条件処理プログラムを登録する
  3. 条件処理プログラムの登録を取り消す
  4. *PSSR エラー処理サブルーチンをコーディングする
この例は、次の 2 つのプロシージャーから成っています。
  • RPGHDLR。範囲外サブストリング・エラーを処理するための ユーザー作成条件処理プログラムからなります。
  • SHOWERR。RPGHDLR プロシージャーをテストします。

SHOWERR は主に RPGHDLR の働きを示すために設計されていますが、2 つが結合したプロシージャーは、ILE 例外処理が「どのように」行われるかを判別する上でも有用です。両方のプロシージャーは、処理されて時に起こる「処置」を QSYSPRT に 書き出します。 調べたい、ILE 例外処理の別の側面をシミュレートするために、これらのプロシージャーを変更することができます。

図 1 にはプロシージャー RPGHDLR のソースを示してありま す。 このプロシージャーは 3 つのプロシージャー・パラメーターを定義します。 すなわち、ILE 条件トークンの構造、SHOWERR と RPGHDLR 間の連絡域へのポインター、および可能な処置、 再開またはパーコレートの指示が入るフィールドです (RPGHDLR は例外をプロモートしません)。

RPGHDLR の基本ロジックは次のとおりです。
  1. メッセージ ID をテストすることによって範囲外エラーであるかを調べる ためのテストをする。
    • 範囲外エラーの場合および SHOWERR が範囲外エラーが無視されることを指示している場合には、'Handling...' を QSYSPRT に書き出して、 処置を「再開」に設定します。
    • 範囲外エラーでない場合には、'Percolating' を QSYSPRT に書き出して、処置を「パーコレート」に設定します。
  2. 戻る。
図 1. 範囲外サブストリング・エラーの条件処理プログラムのソース
      *=================================================================*
      * RPGHDLR: RPG 例外処理プロシージャー。                           *
      *          このプロシージャーは次のことを実行します。             *
      *          RPG 範囲外エラー (RNX0100) の場合には、                *
      *             例外を処理します。                                  *
      *          そうでない場合には、                                   *
      *             例外をパーコレートします。                          *
      *          また、実行したことを印刷します。                       *
      *                                                                 *
      * 注:      これは SHOWERR プロシージャーの例外処理プロシージャー  *
      *          です。                                                 *
      *=================================================================*
     FQSYSPRT   O    F  132        PRINTER

     D RPGHDLR         PR
     D  Parm1                              LIKE(CondTok)
     D  Parm2                          *
     D  Parm3                        10I 0
     D  Parm4                              LIKE(CondTok)

      *-----------------------------------------------------------------*
      * プロシージャー・パラメーター                                    *
      * 1. 入力: 条件トークン構造                                       *
      * 2. 入力: 以下を含んでいる連絡域へのポインター                   *
      *        a. 処理されているプロシージャーの PSDS へのポインター    *
      *        b. ストリング・エラーが有効かどうかを示す標識            *
      * 3. 出力: 例外に対して実行されるべき処置を                       *
      *          識別するコード                                         *
      * 4. 出力: 条件をプロモートすることに決めた場合の新しい条件。     *
      *          この処理プログラムは再開とパーコレートしか実行しない   *
      *          ので、このパラメーターを無視します。                   *
      *-----------------------------------------------------------------*
     D RPGHDLR         PI
     D  InCondTok                          LIKE(CondTok)
     D  pCommArea                      *
     D  Action                       10I 0
     D  OutCondTok                         LIKE(CondTok)
     D CondTok         DS                  BASED(pCondTok)
     D  MsgSev                        5I 0
     D  MsgNo                         2A
     D                                1A
     D  MsgPrefix                     3A
     D  MsgKey                        4A

     D CommArea        DS                  BASED(pCommArea)
     D   pPSDS                         *
     D   AllowError                   1N

     D PassedPSDS      DS                  BASED(pPSDS)
     D   ProcName              1     10

      *
      * 処置コード:
      *
     D Resume          C                   10
     D Percolate       C                   20

      *-----------------------------------------------------------------*
      *      入力条件トークンをポイントする。                           *
      *-----------------------------------------------------------------*
     C                   EVAL      pCondTok = %ADDR(InCondTok)

      *-----------------------------------------------------------------*
      * サブストリング・エラーの場合は、ELSE パーコレートを処理します。 *
      * メッセージ番号 (MsgNo) の値は 16 進であることに注意。           *
      *-----------------------------------------------------------------*
     C                   EXCEPT
     C                   IF        MsgPrefix = 'RNX' AND
     C                             MsgNo     = X'0100' AND
     C                             AllowError = '1'
     C                   EXCEPT    Handling
     C                   EVAL      Action    = Resume
     C                   ELSE
     C                   EXCEPT    Perclating
     C                   EVAL      Action    = Percolate
     C                   ENDIF
     C                   RETURN

      *=================================================================*
      * プロシージャー出力                                              *
      *=================================================================*
     OQSYSPRT   E
     O                                              'HDLR: In Handler for '
     O                       ProcName
     OQSYSPRT   E            Handling
     O                                              'HDLR: Handling...'
     OQSYSPRT   E            Perclating
     O                                              'HDLR: Percolating...'

図 2 は、条件処理プログラム RPGHDLR が登録されている プロシージャー SHOWERR のソースを示します。

プロシージャー・パラメーターには、RPGHDLR へのプロシージャー・ポインター、およびモジュールの PSDS へのポインターを含む連絡域へのポインター、そして範囲外ストリング・エラーを無視できるかどうかを示す標識が含まれます。 さらに、エラーとなる可能性がある配列 ARR1 の定義、 および ILE バインド可能 API の CEEHDLR および CEEHDLU によって使用されるパラメーター・リストの識別を必要とします。

プログラムの基本論理は次のとおりです。
  1. サブルーチン RegHndlr を使用して処理プログラム RPGHDLR を登録する。このサブルーチン は CEEHDLR API を呼び出し、それに RPGHDLR を指すプロシージャー・ポインターを渡します。
  2. RPGHDLR に対して、範囲外エラーが許されることを指示してから、範囲外サブストリング・エラーを生成し、次いで、RPGHDLR が予期せぬ範囲外ストリング・エラーを許さないように標識をオフに設定する。

    処理プログラム RPGHDLR は自動的に呼び出されます。 この処理プログラムは例外を処理し、エラーの後の次の機械語 命令 で処理が再開されることを示します。 次の機械語命令が次の RPG 命令の始めにない場合があるということに注意して ください。

  3. 範囲外配列エラーを生成する。

    再び RPGHDLR が自動的に呼び出されます。 しかし今回は例外を処理できない ので、それをプロシージャーに関連した次の例外処理プログラム、 すなわち *PSSR エラー処理サブルーチンにパーコレートします。

    *PSSR がプロシージャーを取り消します。

  4. CEEHDLU の呼び出しを介して条件処理プログラム RPGHDLR を登録解除する。
  5. 戻る。

RPGHDLR プロシージャーと同様に、SHOWERR は QSYSPRT に書き出しを行って、 処理時に何が起こったかを示します。

図 2. 条件処理プログラム登録のソース
      *=================================================================*
      * SHOWERR:       ユーザー定義の例外処理プログラムを使用した       *
      *                例外処理を示します。                             *
      *=================================================================*
     FQSYSPRT   O    F  132        PRINTER

      *-----------------------------------------------------------------*
      * CEEHDLR API のパラメーター定義は次のとおりです。最初の          *
      * パラメーターは例外を処理するプロシージャーへのプロシージャー・  *
      * ポインターです。2 番目は例外処理プロシージャーに渡される        *
      * 連絡域へのポインターです。この例では、                          *
      * この連絡域にはこのモジュールの PSDS へのポインターと、          *
      * エラーが許されるかどうかを示す                                  *
      * 標識が含まれています。                                          *
      *                                                                 *
      * このプログラム (SHOWERR) が処理されたいかなるエラーも無視しない *
      * ようにするため、RPGHDLR が「許可」するであろうエラーを起こす    *
      * 可能性のあるすべての命令の後で「エラー」標識をチェックします。  *
      * また、プログラムの終了時に、いかなるエラーも見逃さなかった      *
      * ことを確認するためにチェックを行ないます。                      *
      *-----------------------------------------------------------------*
     D pConHdlr        S               *   PROCPTR
     D                                     INZ(%paddr('RPGHDLR'))

      *-----------------------------------------------------------------*
      * 連絡域                                                          *
      *-----------------------------------------------------------------*
     D CommArea        DS                  NOOPT
     D   pPsds                         *   INZ(%ADDR(DSPsds))
     D   AllowError                   1N   INZ('0')

      *-----------------------------------------------------------------*
      * PSDS                                                            *
      *-----------------------------------------------------------------*
     D DSPsds         SDS                  NOOPT
     D   ProcName        *PROC

      *-----------------------------------------------------------------*
      * エラーを起こすために使用される変数                              *
      *-----------------------------------------------------------------*
     D Arr1            S             10A   DIM(5)
     D Num             S              5P 0

      *-----------------------------------------------------------------*
      * CEEHDLR インターフェース
      *-----------------------------------------------------------------*
     D CEEHDLR         PR
     D   pConHdlr                      *   PROCPTR
     D   CommArea                      *   CONST
     D   Feedback                    12A   OPTIONS(*OMIT)

      *-----------------------------------------------------------------*
      * CEEHDLU インターフェース
      *-----------------------------------------------------------------*
     D CEEHDLU         PR
     D   pConHdlr                      *   PROCPTR
     D   Feedback                    12A   OPTIONS(*OMIT)
      *-----------------------------------------------------------------*
      * 処理プログラムを登録し、エラーを生成します。                    *
      *-----------------------------------------------------------------*
     C                   EXSR      RegHndlr

      *-----------------------------------------------------------------*
      *      サブストリング・エラーを生成します。                       *
      *      これはこの例で「許される」エラーです (RPGHDLR は、エラーの *
      *      後で次の命令に戻るための制御を許可するという、例外を処理   *
      *      します)。                                                  *
      *      RPGHDLR は "AllowError" 標識がオンに設定されているとき以外 *
      *      エラーを許しません。これは、例えば SCAN 命令が後で         *
      *      SHOWERR に追加された場合、RPGHDLR はデフォルトでエラーを   *
      *      許可しないことを保証します。                               *
      *-----------------------------------------------------------------*
     C                   Z-ADD     -1            Num
     C                   EVAL      AllowError = '1'
     C     Num           SUBST     'Hello'       Examp            10
     C                   EVAL      AllowError = '0'

      *-----------------------------------------------------------------*
      *      処理プログラムによって例外が処理され、ここで               *
      *      制御が再開されます。                                       *
      *-----------------------------------------------------------------*
     C                   EXCEPT    ImBack

      *-----------------------------------------------------------------*
      *      配列の範囲外エラーを生成します。                           *
      *      これはこの例では「予想された」エラーではありません。       *
      *-----------------------------------------------------------------*
     C                   Z-ADD     -1            Num
     C                   MOVE      Arr1(Num)     Arr1(Num)

      *-----------------------------------------------------------------*
      *      この例外は処理プログラムでは処理されないので、             *
      *      制御はここには戻りません。この例外は                       *
      *      パーコレートされ、制御は *PSSR で再開されます。            *
      *-----------------------------------------------------------------*

      *-----------------------------------------------------------------*
      *      処理プログラムの登録解除                                   *
      *      注: 処理プログラムが登録解除される前に例外が起こった場合   *
      *      は、プロシージャーが取り消される時に自動的に               *
      *      登録解除されます。                                         *
      *-----------------------------------------------------------------*
     C                   EXSR      DeRegHndlr
     C                   SETON                                        LR

      *=================================================================*
      * RegHdlr - 処理プログラムを登録する API の呼び出し               *
      *=================================================================*
     C     RegHndlr      BEGSR
     C                   CALLP     CEEHDLR(pConHdlr : %ADDR(CommArea) : *OMIT)
     C                   ENDSR

      *=================================================================*
      * DeRegHndlr - 処理プログラムを登録解除する API の呼び出し        *
      *=================================================================*
     C     DeRegHndlr    BEGSR
     C                   CALLP     CEEHDLU(pConHdlr : *OMIT)
     C                   ENDSR
      *=================================================================*
      * *PSSR: プロシージャーのエラー処理サブルーチン                   *
      *=================================================================*
     C     *PSSR         BEGSR
     C                   EXCEPT    InPssr
     C                   EXCEPT    Cancelling
      C                   ENDSR     '*CANCL'

      *=================================================================*
      * プロシージャー出力                                              *
      *=================================================================*
     OQSYSPRT   E            ImBack
     O                                              'I''m Back'
     OQSYSPRT   E            InPssr
     O                                              'In PSSR'
     OQSYSPRT   E            Cancelling
     O                                              'Cancelling...'
これらのプロシージャーを試したい場合には、次のステップに従ってください。
  1. 図 1 に示されたソースを使用してプロシージャー RPGHDLR を作成するために、次を入力してください。
    CRTRPGMOD MODULE(MYLIB/RPGHDLR)
  2. 図 2 に示されたソースを使用してプロシージャー SHOWERR を作成するために、次を入力してください。
    CRTRPGMOD MODULE(MYLIB/SHOWERR)
  3. プログラム ERRORTEST を作成するために、次を入力してください。
    CRTPGM PGM(MYLIB/ERRORTEST) MODULE(SHOWERR RPGHDLR)
  4. プログラム ERRORTEST を実行するために、次を入力してください。
    OVRPRTF FILE(QSYSPRT) SHARE(*YES)
    CALL PGM(MYLIB/ERRORTEST)
    出力を以下に示します。
     HDLR: In Handler for SHOWERR
     HDLR: Handling...
     I'm Back
     HDLR: In Handler for SHOWERR
     HDLR: Percolating...
     In PSSR
     Cancelling...