ILEプログラムがソース・デバッグ可能かどうかを判定するのは
比較的簡単である。
ILEプログラムに含まれているモジュールのビューを検索すれば
そこに デバッグ・データ(DBGDTA=10バイト)があり
ソース・デバッグ可能であればそこに*YESと記録されているので
これを判定の材料にするだけでよい。
ただしモジュールの一覧はこのAPIによっていったんユーザー・スペースに
出力されるのでユーザー・スペースを作成してそれに出力された内容を
読み取らねばならないので少し面倒な作業が必要となる。
[CLP: TESTSRC3 ]
ソースはこちらから
0001.00 PGM
0002.00 DCL VAR(&PGMINFO) TYPE(*CHAR) LEN(20)
0003.00 DCL VAR(&PGM) TYPE(*CHAR) STG(*DEFINED) +
0004.00 LEN(10) DEFVAR(&PGMINFO 1)
0005.00 DCL VAR(&PGMLIB) TYPE(*CHAR) STG(*DEFINED) +
0006.00 LEN(10) DEFVAR(&PGMINFO 11)
0007.00 DCL VAR(&ERR) TYPE(*CHAR) LEN(1)
0008.00 DCL VAR(&APIERR) TYPE(*CHAR) LEN(116) +
0009.00 VALUE(X'0000007400000000') /* 2 進数 */
0010.00 DCL VAR(&NULL4) TYPE(*CHAR) LEN(4) +
0011.00 VALUE(X'00000000')
0012.00 /*( Retrieve Program Information (QCLRPGMI) API 変数 )*/
0013.00 DCL VAR(&PGMI0100) TYPE(*CHAR) LEN(1024)
0014.00 DCL VAR(&PGMTYP) TYPE(*CHAR) STG(*DEFINED) +
0015.00 LEN(1) DEFVAR(&PGMI0100 161)
0016.00 DCL VAR(&PGMILEN) TYPE(*CHAR) LEN(4) +
0017.00 VALUE(X'00000400')
0018.00 /*( QUSRTVUS 変数 )*/
0019.00 DCL VAR(&STRPOS) TYPE(*CHAR) LEN(4) +
0020.00 VALUE(X'0000007D') /* 2 進数開始位置 : +
0021.00 125 */
0022.00 DCL VAR(&LENDTA) TYPE(*CHAR) LEN(4) +
0023.00 VALUE(X'00000010') /* 2 進数受取長さ : 16 */
0024.00 DCL VAR(&RCVVAR) TYPE(*CHAR) LEN(16) +
0025.00 VALUE(X'0000000000000000')
0026.00 DCL VAR(&OFFSET) TYPE(*CHAR) LEN(4) /* +
0027.00 2 進数 オフセット */
0028.00 DCL VAR(&NOENTR) TYPE(*CHAR) LEN(4) /* +
0029.00 2 進数項目数 */
0030.00 DCL VAR(&LSTSIZ) TYPE(*CHAR) LEN(4) /* +
0031.00 2 進数リストサイズ */
0032.00 DCL VAR(&DEC08) TYPE(*DEC) LEN(8 0) /* WORK */
0033.00 DCL VAR(&ADDLEN) TYPE(*DEC) LEN(8 0) /* WORK */
0034.00 DCL VAR(&NOENT) TYPE(*DEC) LEN(8 0) /* WORK */
0035.00 DCL VAR(&N) TYPE(*DEC) LEN(8 0) VALUE(1) /* WORK */
0036.00 DCL VAR(&RCVDTA) TYPE(*CHAR) LEN(4096) /* +
0037.00 受取データ */
0038.00 DCL VAR(&DBGDTA) TYPE(*CHAR) LEN(10)
0039.00
0040.00 /*( ユーザー・スペースの作成 )*/
0041.00 CALL PGM(QUSCRTUS) PARM('QBNLPGMI QTEMP ' +
0042.00 'PF ' 1000 ' ' '*ALL ' +
0043.00 'QBNLPGMI 用ユーザー空間 ' '*YES ' +
0044.00 &APIERR)
0045.00 MONMSG CPF9870
0046.00 /*( QBNLPGMI:ILE プログラム情報の検索 API )*/
0047.00 CHGVAR VAR(&PGMINFO) VALUE('PGM201 QTROBJ ')
0048.00 CALL PGM(QBNLPGMI) PARM('QBNLPGMI QTEMP ' +
0049.00 'PGML0100' &PGMINFO &APIERR)
0050.00 IF COND(%SST(&APIERR 5 4) *NE &NULL4) THEN(DO)
0051.00 SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) +
0052.00 MSGDTA('API エラー ') MSGTYPE(*ESCAPE)
0053.00 RETURN
0054.00 ENDDO
0055.00 /*( ユーザー・スペースを検索 )*/
0056.00 /*( プログラムの実行 )*/
0057.00 /*( リストAPIで作成されたユーザー空間の検索 )*/
0058.00 /*( リストデータセクションのオフセットを検索 )*/
0059.00 CALL PGM(QUSRTVUS) PARM('QBNLPGMI QTEMP ' +
0060.00 &STRPOS &LENDTA &RCVVAR)
0061.00 CHGVAR VAR(&OFFSET) VALUE(%SST(&RCVVAR 1 4))
0062.00 CHGVAR VAR(&NOENTR) VALUE(%SST(&RCVVAR 9 4))
0063.00 CHGVAR VAR(&LSTSIZ) VALUE(%SST(&RCVVAR 13 4))
0064.00
0065.00 /*( RCVVAR によって OFFSET,LSTSIZ を受取った )*/
0066.00 CHGVAR VAR(&STRPOS) VALUE(&OFFSET)
0067.00 CHGVAR VAR(&DEC08) VALUE(%BIN(&STRPOS))
0068.00 CHGVAR VAR(&DEC08) VALUE(&DEC08 + 1)
0069.00 CHGVAR VAR(%BIN(&STRPOS)) VALUE(&DEC08)
0070.00 CHGVAR VAR(&LENDTA) VALUE(&LSTSIZ)
0071.00 CHGVAR VAR(&ADDLEN) VALUE(%BIN(&LENDTA))
0072.00 CHGVAR VAR(&NOENT) VALUE(%BIN(&NOENTR))
0073.00 NXTRTV:
0074.00 CALL PGM(QUSRTVUS) PARM('QBNLPGMI QTEMP ' +
0075.00 &STRPOS &LENDTA &RCVDTA)
0076.00 /*( 処理の開始 )*/
0077.00 CHGVAR VAR(&DBGDTA) VALUE(%SST(&RCVDTA 145 10))
0078.00 SNDPGMMSG MSG('DBGDTA=' *CAT &DBGDTA) MSGTYPE(*DIAG)
0079.00 RETURN
0080.00 /*( 処理の終了 )*/
0081.00 IF COND(&N < &NOENT) THEN(DO)
0082.00 CHGVAR VAR(&N) VALUE(&N + 1)
0083.00 CHGVAR VAR(&DEC08) VALUE(%BIN(&STRPOS))
0084.00 CHGVAR VAR(&DEC08) VALUE(&DEC08 + &ADDLEN)
0085.00 CHGVAR VAR(%BIN(&STRPOS)) VALUE(&DEC08)
0086.00 GOTO NXTRTV
0087.00 ENDDO
0088.00 RETURN
0089.00 ENDPGM
[コンパイル]
CRTCLPGM PGM(OBJLIB/TESTSRC3) SRCFILE(SRCLIB/QCLSRC) OPTION(*SRCDBG) AUT(*ALL)
[解説]
0040.00 /*( ユーザー・スペースの作成 )*/
0041.00 CALL PGM(QUSCRTUS) PARM('QBNLPGMI QTEMP ' +
0042.00 'PF ' 1000 ' ' '*ALL ' +
0043.00 'QBNLPGMI 用ユーザー空間 ' '*YES ' +
0044.00 &APIERR)
によってユーザー・スペースをQTEMPに作成して
0046.00 /*( QBNLPGMI:ILE プログラム情報の検索 API )*/
0047.00 CHGVAR VAR(&PGMINFO) VALUE('PGM201 QTROBJ ')
0048.00 CALL PGM(QBNLPGMI) PARM('QBNLPGMI QTEMP ' +
0049.00 'PGML0100' &PGMINFO &APIERR)
によってユーザー・スペースにモジュールの一覧を出力して
0074.00 CALL PGM(QUSRTVUS) PARM('QBNLPGMI QTEMP ' +
0075.00 &STRPOS &LENDTA &RCVDTA)
でユーザー・スペースを読み取る。この処理はリストAPIで共通の処理であるから
覚えておくと良い。
0076.00 /*( 処理の開始 )*/
0077.00 CHGVAR VAR(&DBGDTA) VALUE(%SST(&RCVDTA 145 10))
0078.00 SNDPGMMSG MSG('DBGDTA=' *CAT &DBGDTA) MSGTYPE(*DIAG)
0079.00 RETURN
にあるように デバッグ・データに *YESと入っていればソース・デバッグ可能であると
判定することができる。
参考までに ILEプログラムのソース情報は RTVOBJD では取得することはできない。
ILEプログラムのソース情報はモジュール別に管理されているので
0077.00 CHGVAR VAR(&DBGDTA) VALUE(%SST(&RCVDTA 145 10))
のように&RCVDTAから取得しなければならない。
つまりILEプログラムのソース情報の取得は今回の紹介と同じ方法で行うことになる。
OPMに比べてILEの処理は進化していることがよくわかる。
後でOPMとILEのどちらも判定できるツールを公開する予定である。
