C/400

92. API: QUSLOBJ : オブジェクトのリスト

QUSLOBJ も使用頻度の高い API であり、オブジェクトの一覧をユーザー・スペースに
出力して、それを検索して解析したり別の一覧表に出力するような目的のために使用される。
API の結果の出力方法は QUSROBJD で紹介したレシーバー変数に出力する場合と
結果の項目が複数個ある場合は、この QUSLOBJ のようにユーザー・スペースに
出力する方法に分かれる。

QUSLOBJ : オブジェクトのリスト

パラメータ

必須パラメータ・グループ:

1.ユーザー・スペース修飾名入力Char(20)
2.形式名入力Char(8)
3.オブジェクト修飾名入力Binary(4)
4.オブジェクト・タイプ入力Char(10)の配列(*)

任意選択パラメータ:

5.エラー・コード入出力Char(*)

任意選択パラメータ:

6.権限制御入力Char(*)
7.選択制御入力Char(*)

【解説】

結果の内容を受け取るためのユーザー・スペース ( *USRSPC ) は QUSLOBJ を実行する前には
予め作成して準備しておかなければならない。
後で示すサンプル・ソースには、この作業も含めてある。

形式名 は、

OBJL0100 形式・・・・・・オブジェクト名(最高速)
OBJL0200 形式・・・・・・テキスト記述および拡張属性
OBJL0300 形式・・・・・・基本オブジェクト情報
OBJL0400 形式・・・・・・作成情報
OBJL0500 形式・・・・・・保管および復元情報
OBJL0600 形式・・・・・・使用状況情報
OBJL0700 形式・・・・・・すべてのオブジェクト情報(最低速)

形式によって受け取る情報の詳細は後述する。

オブジェクト修飾名( オブジェクト名 ) + ( ライブラリー名 ) であるが次の特殊値を
指定することができる。

*ALL・・・・・・すべてのライブラリー
*ALLUSR・・・・・・すべてのユーザー・ライブラリー
( ユーザー・ライブラリーとは 名前が Q で始まっていないライブラリーであり、
#CGULIB, #RPGLIB, #COBLIB, #SDALIB, #DFULIB, #SEULIB, #DSULIB を除く。)
*CURLIB・・・・・・ジョブの現行ライブラリー
*LIBL・・・・・・ライブラリー・リスト
*USRLIBL・・・・・・ジョブのライブラリー・リストのユーザー部分だけ

オブジェクト・タイプ は、特定のオブジェクト・タイプ または *ALL を指定する。
権限制御選択制御 はあまり指定することがないので必要があれば IBM API 解説書を参照のこと。
最初にユーザー・スペースを作成するために ユーザー・スペースの作成 API である QUSCRTUS を紹介する。

QUSCRTUS : ユーザー・スペースの作成 API

パラメータ

必須パラメータ・グループ:

1.ユーザー・スペース修飾名入力Char(20)
2.拡張属性入力Char(10)
3.初期サイズ入力Binary(4)
4.初期値入力Char(1)
5.共通権限入力Char(10)
6.テキスト記述入力Char(20)

任意選択パラメータ:

7.置換入力Char(10)
8.エラー・コード入出力Char(*)
【解説】

ユーザー・スペース修飾名 は例えば、「 USRSPC   QTEMP     」 などのように任意の名前をつけて
QTEMP に作成することが多い。
拡張属性 は、ユーザー・スペースの拡張属性であり使用するユーザーが識別できるものでよい。
例えば、PF, LF, DSPF または SAVF などでよい。
初期サイズ は最初にユーザー・スペースを作成するサイズ ( バイト数 ) であるが 1000 バイトあたりに
定義しておけば不測の場合は自動的に OS によって拡張される。
初期値 は最初にユーザー・スペースに埋め込む 1 バイトの Char である。NULL かまたは ブランク でよい。
共通権限AUT であるので通常は *ALL として作成しておけばよい。
テキスト記述 は文字通りこのユーザー・スペースのテキストである。
置換 は任意選択とはなっているが必須であろう。
*YES として指定しておけば QUSCRTUS は、作成するユーザー・スペースが存在していても
エラーを発生することなく上書きで作成してくれる便利な機能である。
従って置換には必ず *YES を指定して作成することが肝要である。
QUSCRTUS の実行例は次のとおりである。

/*(1) ユーザー・スペースの作成 */                                    
typedef struct {                                                     
   char name[10];                                                    
   char lib[10];                                                     
} USNAME;                                                            
USNAME usname;                                                       
    :                                                                
    :                                                                
errcode.BYTESPRO = 160;                                              
errcode.BYTESAVL = 0;                                                
memcpy(usname.name, "LIBSPC    ", 10);                               
memcpy(usname.lib,  "QTEMP     ", 10);                               
QUSCRTUS(&usname, "PF        ", 1000, " ", "*ALL      ",             
            "QUSLOBJ ユーザー・スペース ", "*YES      ", &errcode);  
if(errcode.BYTESAVL != 0){/* APIERR */                               
  printf("ApiError MSGID = %s\n", errcode.MSGID);                    
  getchar();                                                         
  return;                                                            
}/* APIERR */                                                        

次に API : QUSLOBJ によって *ALLUSR のライブラリー一覧を ユーザー・スペースに出力する。
QUSLOBJ の実行自体は次のように簡単である。

/*(2) QUSLOBJ の実行 */                                                        
QUSLOBJ(&usname, "OBJL0300", "*ALLUSR   *ALL      ", "*LIB      ", &errcode);  

結果の ユーザー・スペースの読み取りは API : QUSRTVUS によって検索する。
API : QUSRTVUS もユーザー・スペースを検索するために良く使う API であり
使用方法はどのような場合でも全く同じである。

QUSRTVUS : ユーザー・スペースの読み取り API

パラメータ

必須パラメータ・グループ:

1.ユーザー・スペース修飾名入力Char(20)
2.開始位置入力Birary(4)
3.データの長さ入力Binary(4)
4.レシーバー変数出力Char(*)

任意選択パラメータ:

5.エラー・コード入出力Char(*)

ユーザー・スペースの構造はすべて同じであり、最初のヘッダー部分に レコード数1 レコードの長さ
登録されている。従って 最初にヘッダー部分を読んで最初のデータの開始位置 ( offset ) と
レコードの長さ( size ) を取得してから 項目数( inspace.number_of_entries ) の分だけ
LOOP してデータを読み取ればよい。

/*(3) QUSRTVUS によるユーザー・スペースの検索 */                     
typedef _Packed struct header_struct {                               
     char user_data[64];                                             
     int  generic_header_size;                                       
     char header_version[4];                                         
     char format_name[8];                                            
     char program_name[10];                                          
     char time_generated[13];                                        
     char information_status;                                        
     int  usrspc_used;                                               
     int  parm_section_offset;                                       
     int  parm_section_size;                                         
     int  header_section_offset;                                     
     int  header_section_size;                                       
     int  list_section_offset; /*( 最初の開始位置 )*/                
     int  list_section_size;                                         
     int  number_of_entries;   /*( 項目数 )*/                        
     int  size_of_entry;       /*( 1 項目の長さ )*/                  
} HEADER_STRUCT;                                                     
HEADER_STRUCT inspace;                                               
      :                                                              
      :                                                              
QUSRTVUS(&usname, 0x01, sizeof(inspace), &inspace, &errcode);        
offset = inspace.list_section_offset +1;                             
size   = inspace.size_of_entry;                                      
                                                                     
for(i = 0; i<inspace.number_of_entries; i++){/*for-loop*/            
  QUSRTVUS(&usname, offset, size, &objl0300, &errcode);              
  /*--------------( 処理の開始 )-----------------*/                  
  memcpy(name, objl0300.Object_Name_Used, 10);                       
  name[10] = 0x00;                                                   
  printf("[%d] Object_Name = [%s]\n", i+1, name);                    
  /*--------------( 処理の終了 )-----------------*/                  
  offset += inspace.size_of_entry;                                   
}/*for-loop*/                                                        

ユーザー・スペースの読み取りは ( 処理の開始 ) 〜 ( 処理の終了 ) が変わるだけで
ヘッダー構造 ( HEADER_STRUCT ) もつねに同じである。

以上の処理をひとつのソースにまとめると次のようになる。

0001.00 #include <stdio.h>                                                               
0002.00 #include <stdlib.h>                                                              
0003.00 #include <string.h>                                                              
0004.00 #include <QUSCRTUS.h>                                                            
0005.00 #include <QUSLOBJ.h>                                                             
0006.00 #include <QUSRTVUS.h>                                                            
0007.00 #include <signal.h>                                                              
0008.00 #include <errno.h>                                                               
0009.00                                                                                  
0010.00 #define TRUE         0                                                           
0011.00 #define FALSE       -1                                                           
0012.00   volatile _INTRPT_Hndlr_Parms_T ca;                                             
0013.00 typedef struct {                                                                 
0014.00    int  BYTESPRO;                                                                
0015.00    int  BYTESAVL;                                                                
0016.00    char MSGID[7];                                                                
0017.00    char RESRVD;                                                                  
0018.00    char EXCPDATA[100];                                                           
0019.00 } ERRSTRUCTURE;     /* Define the error return structure            */           
0020.00 ERRSTRUCTURE  errcode;/* Error Code Structure for RCVMSG      */                 
0021.00                                                                                  
0022.00 void main(void){                                                                 
0023.00 typedef struct {                                                                 
023.00 typedef struct {                                                                  
024.00    char name[10];                                                                 
025.00    char lib[10];                                                                  
026.00 } USNAME;                                                                         
027.00 USNAME usname;                                                                    
028.00 typedef _Packed struct header_struct {                                            
029.00      char user_data[64];                                                          
030.00      int  generic_header_size;                                                    
031.00      char header_version[4];                                                      
032.00      char format_name[8];                                                         
033.00      char program_name[10];                                                       
034.00      char time_generated[13];                                                     
035.00      char information_status;                                                     
036.00      int  usrspc_used;                                                            
037.00      int  parm_section_offset;                                                    
038.00      int  parm_section_size;                                                      
039.00      int  header_section_offset;                                                  
040.00      int  header_section_size;                                                    
041.00      int  list_section_offset; /*( 最初の開始位置 )*/                             
042.00      int  list_section_size;                                                      
043.00      int  number_of_entries;   /*( 項目数 )*/                                     
044.00      int  size_of_entry;       /*( 1 項目の長さ )*/                               
045.00 } HEADER_STRUCT;                                                                  
046.00 HEADER_STRUCT inspace;                                                            
0047.00   int offset, size, i, len;                                                      
0048.00   char name[11];                                                                 
0049.00   Qus_OBJL0300_t objl0300;                                                       
0050.00                                                                                  
0051.00   printf("** TESTUSLO : オブジェクト一覧表 **\n");                               
0052.00   getchar();                                                                     
0053.00   /*(1) ユーザー・スペースの作成 */                                              
0054.00   errcode.BYTESPRO = 160;                                                        
0055.00   errcode.BYTESAVL = 0;                                                          
0056.00   memcpy(usname.name, "LIBSPC    ", 10);                                         
0057.00   memcpy(usname.lib,  "QTEMP     ", 10);                                         
0058.00   QUSCRTUS(&usname, "PF        ", 1000, " ", "*ALL      ",                       
0059.00               "QUSLOBJ ユーザー・スペース ", "*YES      ", &errcode);            
0060.00   if(errcode.BYTESAVL != 0){/* APIERR */                                         
0061.00     printf("ApiError MSGID = %s\n", errcode.MSGID);                              
0062.00     getchar();                                                                   
0063.00     return;                                                                      
0064.00   }/* APIERR */                                                                  
0065.00                                                                                  
0066.00   /*(2) QUSLOBJ の実行 */                                                        
0067.00   QUSLOBJ(&usname, "OBJL0300", "*ALLUSR   *ALL      ", "*LIB      ", &errcode);  
0068.00                                                                                  
0069.00   /*(3) QUSRTVUS によるユーザー・スペースの検索 */                               
0070.00   QUSRTVUS(&usname, 0x01, sizeof(inspace), &inspace, &errcode);                  
0071.00   offset = inspace.list_section_offset +1;                                       
0072.00   size   = inspace.size_of_entry;                                                
0073.00                                                                                  
0074.00   printf("count = %d\n", inspace.number_of_entries);                             
0075.00   getchar();                                                                     
0076.00   for(i = 0; i<inspace.number_of_entries; i++){/*for-loop*/                      
0077.00     QUSRTVUS(&usname, offset, size, &objl0300, &errcode);                        
0078.00     /*--------------( 処理の開始 )-----------------*/                            
0079.00     memcpy(name, objl0300.Object_Name_Used, 10);                                 
0080.00     name[10] = 0x00;                                                             
0081.00     printf("[%d] Object_Name = [%s]\n", i+1, name);                              
0082.00     /*--------------( 処理の終了 )-----------------*/                            
0083.00     offset += inspace.size_of_entry;                                             
0084.00   }/*for-loop*/                                                                  
0085.00 }                                                                                
【解説】

QUSLOBJ 以外の別の ユーザー・スペースに出力する API の場合も

0067.00   QUSLOBJ(&usname, "OBJL0300", "*ALLUSR   *ALL      ", "*LIB      ", &errcode);  

と、

0078.00     /*--------------( 処理の開始 )-----------------*/                            
0079.00     memcpy(name, objl0300.Object_Name_Used, 10);                                 
0080.00     name[10] = 0x00;                                                             
0081.00     printf("[%d] Object_Name = [%s]\n", i+1, name);                              
0082.00     /*--------------( 処理の終了 )-----------------*/                            

が変わるだけでありその他は同じソースとなるはずである。
従ってこの例はコピーして繰り返し参照して使用することになるだろう。