C/400

109. S/38 モードで作成された DSPF を調べるには ?

System i が AS/400 に始まって iSeries や Systemi i、 IBM i などの名前に変遷してきた中で
今さら S/38 (System 38)でもないと思われるが S/38 のDNAの遍歴は立派に今でも System i に
残っていて、毎日のように見かける QCPFMSG は S/38 の OS の名前が QCPF であったことに由来している。

RPG でも RPG38 というオブジェクト属性の RPGプログラムが現存しているのと同様に
S/38 環境下で作成されたと思われる DSPF38 も残っている。

問題は DSPF38 も System i 環境でもそのままで動作するのだが API : QDFRTVFD によって
ファイル構造を調べようとすると

    CPF0679 : オブジェクト xxxx が表示装置ファイルでない

とのエラーが戻ってきて QDFRTVFD は動作しない。

オブジェクト属性 DSPF38 を強制的に DSPF に書き換える API も存在しない。
( API : QLICVTTP :タイプの変換は オブジェクト・タイプを MI などで使用する HEX コードに
  変換するものであってオブジェクト・タイプそのものを変換するわけではない。
  API : QLICOBJD :オブジェクト記述の変換ユーザー定義を変更することはできるが
  オブジェクト・タイプを変換することはできない。)

ライブラリー QSYS38 は存在しているが QSYS38 の中には S/38 用の QDFRTVFD *PGM は存在しない。
そこで考え出された方法とは

DSPF38 のソースを検索して、そのソースから QTEMP に一時的に DSPF を作成して
それを QDFRTVFD で調査する

という方法である。

弊社の製品の中では次のように QDFRTVFDCPF0679 が発生した場合は QDFRTVFD38 という自前で作成した
関数を呼び出すようにしている。

 QDFRTVFD(&qdffbase_t, sizeof(QDFFBASE_t),"DSPF0100",  DSPFFLIB, &errcode);
 if(errcode.BYTESAVL != 0){/* APIERR */                              
   if(strncmp(errcode.MSGID, "CPF0679", 7) == 0){/* DSPF38 */        
     if((QDFRTVFD38(formatBuf, &format_size, "DSPF0100", DSPFFLIB,   
        &errcode)) == FALSE){/* S38 でも失敗 */                      
       return FALSE;                                                 
     }/* S38 でも失敗 */                                             
   }/* DSPF38 */                                                     
   return FALSE;                                                     

関数 : QDFRTVFD とは先に紹介したように、QTEMP に DSPF を *NOLIST *NOSOURCE で作成しているので
パフォーマンス的には何の問題もない。

【QDFRTVFD38】
/***************************************************************/  
int  QDFRTVFD38(void *formatBuf, int* format_size, char* FORMAT,   
                char* DSPFFLIB, void *errcode)                     
/***************************************************************/  
{                                                                  
  Qus_OBJD0200_t objd0200;                                         
  ERRSTRUCTURE   apierr;                                           
  char srcf[11], srcflib[11], srcmbr[11], cmd[128], dspfflib[21];  
  int  len;                                                        
  QDFFBASE_t  qdffbase_t;                                          
                                                                   
  apierr.BYTESPRO = 160;                                           
  apierr.BYTESAVL = 0;                                             
  QUSROBJD(&objd0200, sizeof(Qus_OBJD0200_t), "OBJD0200", DSPFFLIB,
           "*FILE     ", &apierr);                                 
  memcpy(srcf, objd0200.Source_File_Name, 10);                     
  srcf[10] = 0x00;                                                 
  len = triml(srcf, ' '); if(len > 0) srcf[len] = 0x00;            
  memcpy(srcflib, objd0200.Source_File_Lib_Name, 10);              
  srcflib[10] = 0x00;                                              
  len = triml(srcflib, ' '); if(len > 0) srcflib[len] = 0x00;      
  memcpy(srcmbr, objd0200.Source_File_Mbr_Name, 10);                   
  srcmbr[10] = 0x00;                                                   
  len = triml(srcmbr, ' '); if(len > 0) srcmbr[len] = 0x00;            
                                                                       
  sprintf(cmd, "CRTDSPF QTEMP/%s SRCFILE(%s/%s) LVLCHK(*NO)           
  OPTION(*NOSRC *NOLIST) AUT(*ALL)", srcmbr, srcflib, srcf);           
  if((system(cmd)) != ERROR){/* 成功 */                                
    memcpy(dspfflib, DSPFFLIB, 20);                                    
    strcpy(&dspfflib[10], "QTEMP     ");                               
    QDFRTVFD(&qdffbase_t, sizeof(QDFFBASE_t), "DSPF0100", dspfflib, &apiierr); 
    if(apierr.BYTESAVL != 0){/* APIERR */                              
      return FALSE;                                                    
    }/* APIERR */                                                      
    /* format_size を動的に確保 */                                     
    *format_size = qdffbase_t.WDFFSIZE;                                
    formatBuf = (char*)malloc(*format_size + 1);                       
    QDFRTVFD(formatBuf, *format_size, "DSPF0100", dspfflib, &apierr);  
    if(apierr.BYTESAVL != 0){/* APIERR */                              
      free(formatBuf);                                                 
      return FALSE
    }/* APIERR */ 
    return TRUE;  
  }/* 成功 */     
                  
  return TRUE;    
}