CL

190. ILEプログラムのソース・デバッグ可否を判定するには

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のどちらも判定できるツールを公開する予定である。