C400

141. CCSIDを特定するAPI: QTQSCSPの使い方

ここで紹介する技術はCCSIDを理解するための一番奥深い話である。
CCSIDを本当に理解したい方はC言語がわからなくてもぜひ最後まで読んで欲しい。
 
IBM iでは様々なオブジェクトなどにCCSIDが埋め込まれているが
CCSIDとは複数のコードの組み合わせを代表したコードである。
CCSIDとは

(コードページ + グラフィック・コード) * N + ES 符号化形式

の一般式で表現することができる。
つまり

(コードページ + グラフィック・コード)を N個(=複数個)組み合わせたものに
ES 符号化形式というコードをさらに組み合わせたものを代表するコードである。
例えばスプールであればスプールの属性には

  文字識別コード :                                
  図形文字セット . . . . . . . . . . . :   1172 
  コード・ページ . . . . . . . . . . . :   290  

 文字識別コード :                                
  図形文字セット . . . . . . . . . . . :   *DEVD
  コード・ページ . . . . . . . . . . . :   

のように示されている場合がある。
スプールの場合はこの

  文字識別コード(コードページ=Code Page)

  図形文字セット(グラフィック・コードGraphic Code)

の一組だけではCCSIDは決まらない。

CCSID コードページ グラフィック・コード ES符号化形式
37 37 697 0x1100
5026 290
300
1172
370
0x1301
5035
300
1027 1172
370
0x1301
1399 1027
300
65535
65535
0x1301

のようにしてCCSIDが決定される。
この図でわかるようにCCSID:5026は

コードページ グラフィック・コード
290 1172 (=>半角部分)
300 370  (=>漢字の部分)

と二組の組合せを持っている。

さてこれらのコード・ページやグラフィック・コード, ES符号化形式から
CCSIDを決定するAPIは QTQSCSPという名前のAPIであるが
さらに問題なのはこのAPIの解説が悪くて
コード・ページやグラフィック・コード, ES符号化形式という用語を
一切使っていない。

API: QTQSCSP の解説では

CS: グラフィック・コード
CP: コードページ
ES: 符号化形式(ES)

という対応である。

QTQSCSP((CS,CP)の配列, 配列の個数, ES(符号化形式), 戻り値のCCSID, ESR, 結果の理由の配列)

という型式である。
 本編はAPI: QTQSCSP の解説である。
IBM マニュアルを読んでも API: QTQSCSP の解説を理解できる人は少ないと思う。
このように用語が全く統一されていないからである。
CS=Graphic Code Page とわかる人が世界中に何人いるのだろうか?
恐らくこのAPIの解説を書いた人もCCSIDのことは理解していないのではないかと思う。

QSYSINC/H に定義されている関数のプロトタイプは

 /******************************************************************/
 /* Prototype for calling QTQSCSP API.                             */
 /******************************************************************/
 void QTQSCSP (void *,           /* CSCPL                          */
               int *,            /* N1                             */
               int *,            /* ESIN                           */
               int *,            /* CCSIDR                         */
               int *,            /* ESR                            */
               void *);          /* FB                             */

 である。

 

[コマンド: CHKCCSID2 ]

ソースはこちらから

0001.00              CMD        PROMPT('CCSID 検査 ')                         
0002.00              PARM       KWD(FILE) TYPE(*NAME) LEN(10) MIN(1) +        
0003.00                           FILE(*IN) EXPR(*YES) +                      
0004.00                           PROMPT(' スプール・ファイル ' 1)            
0005.00              PARM       KWD(JOB) TYPE(Q0406) DFT(*) SNGVAL((*)) +     
0006.00                           PROMPT(' ジョブ名 ' 3)                      
0007.00              PARM       KWD(SPLNBR) TYPE(*INT4) DFT(*ONLY) RANGE(1 +  
0008.00                           999999) SPCVAL((*ONLY 0) (*LAST -1) (*ANY + 
0009.00                           -2)) EXPR(*YES) +                           
0010.00                           PROMPT(' スプール・ファイル番号 ' 4)        
0011.00 Q0406:       QUAL       TYPE(*NAME) +                                 
0012.00                         LEN(10) +                                     
0013.00                         MIN(1) +                                      
0014.00                         EXPR(*YES)                                    
0015.00              QUAL       TYPE(*NAME) +                                 
0016.00                         LEN(10) +                                     
0017.00                         EXPR(*YES) +                                  
0018.00                         PROMPT(' ユーザー ')                          
0019.00              QUAL       TYPE(*CHAR) +                                 
0020.00                         LEN(6) +                                      
0021.00                         RANGE( +                                      
0022.00                           '000000' +                                  
0023.00                           '999999') +                                 
0024.00                         FULL(*YES) +    
0025.00                         EXPR(*YES) +    
0026.00                         PROMPT(' 番号 ')


 

[コンパイル]

CRTCMD CMD(OBJLIB/CHKCCSID2) PGM(OBJLIB/CHKCCSID2C) SRCFILE(SRCLIB/QCMDSRC) AUT(*ALL)

[実行]

                            CCSID 検査  (CHKCCSID2)                          
                                                                             
 選択項目を入力して,実行キーを押してください。                              
                                                                             
 スプール・ファイル  . . . . . .   QPQUPRFIL      名前                       
 ジョブ名  . . . . . . . . . . .   *              名前 , *                   
   ユーザー  . . . . . . . . . .                  名前                       
   番号  . . . . . . . . . . . .                 000000-999999               
 スプール・ファイル番号  . . . .   *LAST         1-999999, *ONLY, *LAST, *ANY
                                                                             

[CLP: CHKCCSID2C ]

ソースはこちらから

0001.00              PGM        PARM(&SPLF &JOBINFO &SPLNO)                   
0002.00 /*---------------------------------------------------------*/         
0003.00 /*   CHKCCSID2C :   CCSID 検査 2                           */         
0004.00 /*---------------------------------------------------------*/         
0005.00              DCL        VAR(&SPLF) TYPE(*CHAR) LEN(10)                
0006.00              DCL        VAR(&JOBINFO) TYPE(*CHAR) LEN(26)             
0007.00              DCL        VAR(&JOB) TYPE(*CHAR) LEN(10)                 
0008.00              DCL        VAR(&USER) TYPE(*CHAR) LEN(10)                
0009.00              DCL        VAR(&JOBNBR) TYPE(*CHAR) LEN(6)               
0010.00              DCL        VAR(&SPLNO) TYPE(*INT) LEN(4)                 
0011.00              DCL        VAR(&MSG) TYPE(*CHAR) LEN(132)                
0012.00              DCL        VAR(&MSGID) TYPE(*CHAR) LEN(7)                
0013.00              DCL        VAR(&MSGDTA) TYPE(*CHAR) LEN(132)             
0014.00              DCL        VAR(&MSGF) TYPE(*CHAR) LEN(10)                
0015.00              DCL        VAR(&MSGFLIB) TYPE(*CHAR) LEN(10)             
0016.00              MONMSG     MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))       
0017.00                                                                       
0018.00              CALL       PGM(QUATTRO/CHKCCSID2) PARM(&SPLF &JOBINFO +  
0019.00                           &SPLNO &MSGID &MSG &MSGDTA)                 
0020.00              IF         COND(&MSGID *EQ ' ') THEN(GOTO CMDLBL(SNDMSG))
0021.00              CHGVAR     VAR(&MSGF) VALUE('QCPFMSG   ')                
0022.00              CHGVAR     VAR(&MSGFLIB) VALUE('QSYS      ')             
0023.00              GOTO       SNDMSG                                        
0024.00              RETURN                                                   
0025.00                                                                       
0026.00  ERROR:      RCVMSG     MSGTYPE(*LAST) RMV(*NO) MSG(&MSG) +           
0027.00                           MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) + 
0028.00                           MSGFLIB(&MSGFLIB)                           
0029.00  SNDMSG:     IF         COND(&MSGID *EQ ' ') THEN(DO)                 
0030.00              SNDPGMMSG  MSG(&MSG) MSGTYPE(*DIAG)                      
0031.00              ENDDO                                                    
0032.00              ELSE       CMD(DO)                                       
0033.00              SNDPGMMSG  MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +          
0034.00                           MSGDTA(&MSGDTA) MSGTYPE(*ESCAPE)            
0035.00              ENDDO                                                    
0036.00              ENDPGM  


                                                                               

[コンパイル]

CRTCLPGM PGM(OBJLIB/CHKCCSID2C) SRCFILE(SRCLIB/QCLSRC) OPTION(*SRCDBG) AUT(*ALL)
{ C/400: CHKCCSID2C ]

ソースはこちらから

0001.00 /********************************************************************/ 
0002.00 /*                                                                  */ 
0003.00 /*   CHKCCSID :  CCSID 検査                                         */ 
0004.00 /*                                                                  */ 
0005.00 /*          Office Quattro Co,.Ltd 2014/04/28 15:55:28 created      */ 
0006.00 /*                                                                  */ 
0007.00 /*          CRTBNDC QUATTRO/CHKCCSID R610SRC/QCSRC2                 */ 
0008.00 /*                   TERASPACE(*YES *TSIFC) STGMDL(*TERASPACE)      */ 
0009.00 /*                                                                  */ 
0010.00 /********************************************************************/ 
0011.00 #pragma comment(COPYRIGHT, "(C) CopyRight                             
0012.00 Office Quattro.Corp. 2014- All right reserved. Users Restricted       
0013.00 Rights - Use, duplication or disclosure restricted by Office Quattro  
0014.00 Corp. Licenced Materials-Property of Office Quattro.")                 
0015.00 #include                                                      
0016.00 #include                                                     
0017.00 #include                                                     
0018.00 #include  /* triml */                                      
0019.00 #include                                                     
0020.00 #include                                                      
0021.00 #include "asnet.src/h(QUSRSPLA)" /* V5R2M0-V6R1M0 共通 */              
0022.00 #include                                                     
0023.00 #include               /* QtqValidateCCSID */                
0024.00 #include                                                  
0025.00 #include                                                   
0026.00 #include                                                   
0027.00                                                                       
0028.00 #define TRUE         0                                                
0029.00 #define FALSE       -1                                                
0030.00 #define UNKNOWN     -2                                                
0031.00 #define MAX_HEAP_SIZE     16711600   /* 高速ヒープ・サイズ 16MB*/     
0032.00 #define TERA_HEAP_SIZE   214748324   /* 高速ヒープ・サイズ 2GB */     
0033.00 #define MAX_USRSPACE     16776704                                     
0034.00 #define JAPAN     1399                                                
0035.00 #define CHINA     935                                                 
0036.00 #define HONGKONG  937                                                 
0037.00 #define KOREA     933                                                 
0038.00 #define USA       37                                                  
0039.00   volatile _INTRPT_Hndlr_Parms_T ca;                                  
0040.00 typedef struct {                                                      
0041.00    int  BYTESPRO;                                                     
0042.00    int  BYTESAVL;                                                     
0043.00    char MSGID[7];                                                     
0044.00    char RESRVD;                                                       
0045.00    char EXCPDATA[132];                                                
0046.00 } ERRSTRUCTURE;     /* Define the error return structure            */
0047.00 ERRSTRUCTURE  errcode;/* Error Code Structure for RCVMSG      */      
0048.00 typedef struct {                                                        
0049.00    char NM[10];                                                         
0050.00    char LIB[10];                                                        
0051.00 } QNAME;     /* Define the qualified name                            */ 
0052.00 QNAME         inname;                  /*  Qualified user space name */ 
0053.00 char   os400[6];            /* OS/400 バージョン */                     
0054.00 /*************************************************************/         
0055.00 /*       内 部 使 用  関  数                          */         
0056.00 /*************************************************************/         
0057.00 void  GetParam(int argc, char *argv[]);                                 
0058.00 void  INZSR(void);                                                      
0059.00 int   getSpoolattr(char* splf, char* jobinfo, int splno);               
0060.00 char* getLanguage(int ccsid);                                           
0061.00 /*************************************************************/         
0062.00 /*       IMPORT  関  数                            */         
0063.00 /*************************************************************/         
0064.00 /*************************************************************/         
0065.00 /*       IMPORT  変  数                            */         
0066.00 /*************************************************************/         
0067.00 /*************************************************************/         
0068.00 /*       外 部 呼 出 し  関  数                      */         
0069.00 /*************************************************************/         
0070.00 /*************************************************************/         
0071.00 /*        グ ロ ー バ ル 変 数                         */         
0072.00 /*************************************************************/         
0073.00   /*------( 受取りパラメータ値 )----------*/                            
0074.00   char SPLF[11], JOBINFO[27], MSGID[8], MSG[133], MSGDTA[133];          
0075.00   int  SPLNO;                                                           
0076.00   /*------( 受取りパラメータ値 )----------*/                            
0077.00   char job[11], user[11], jobnbr[7], LANG[14];                          
0078.00   int  get_ccsid, Spooled_File_Size, job_ccsid, txt_ccsid;              
0079.00   char DBCS_SOSI[10], WHY[48];                                          
0080.00 typedef struct {                                                        
0081.00   Qus_SPLA0200_t spla0200;                                              
0082.00   char           Options[20];                                           
0083.00 } Qsp_SPLA0200_t;                                                       
0084.00 Qsp_SPLA0200_t  splinfo;                                                
0085.00 long spl_size;  /* スプール・バッファー・サイズ */                      
0086.00 char* spool_buf;                                                        
0087.00 int   chk_table[4], CCSID_of_Job;                                       
0088.00 char  Dev_File_Lib[11], Dev_File_Name[11];                              
0089.00 /********************************************************************/  
0090.00 /*            m  a  i  n --- main module of this pgm                */  
0091.00 /*                                                                  */  
0092.00 /*           1. SPLF                                     */  
0093.00 /*                      2. JONINFO                                  */  
0094.00 /*                      3. SPLNO                                    */  
0095.00 /*                      4. MSGID                                    */  
0096.00 /*                      5. MSG                                      */        
0097.00 /*                      6. MSGDTA                                   */        
0098.00 /*                                                                  */        
0099.00 /*------------------------------------------------------------------*/        
0100.00                                                                               
0101.00 int  main(int argc, char *argv[]){                                            
0102.00    int ccsid, rc;                                                             
0103.00                                                                               
0104.00    #pragma exception_handler(MONMSG, ca, 0, _C2_MH_ESCAPE,                   
0105.00                                             _CTLA_HANDLE)                     
0106.00    GetParam(argc, argv);  /*[ パラメータの取得 ]*/                            
0107.00    INZSR();               /*[ 初期設定 ]*/                                    
0108.00                                                                               
0109.00    if((ccsid = getSpoolattr(SPLF, JOBINFO, SPLNO)) == FALSE){/* 実行   JOB */ 
0110.00      memcpy(argv[4], MSGID, 7);                                               
0111.00      memcpy(argv[5], MSG, 132);                                               
0112.00      memcpy(argv[6], MSGDTA, 132);                                            
0113.00      exit(-1);                                                                
0114.00    }/* 実行 JOB */                                                            
0115.00    if(ccsid == UNKNOWN){/* 装置 */                                            
0116.00      printf("[%d] ccsid is UNKNOWn", __LINE__);                              
0117.00      getchar();                                                               
0118.00    }/* 装置 */                                                                
0119.00    exit(0);                                                                   
0120.00                                                           
0121.00 MONMSG:                                                   
0122.00    #pragma disable_handler                                
0123.00    exit(0);                                               
0124.00 }                                                         
0125.00 /*************************************/                   
0126.00 void  GetParam(int argc, char *argv[])                    
0127.00 /*************************************/                   
0128.00 {                                                         
0129.00    memcpy(SPLF, argv[1], 10);                             
0130.00    SPLF[10] = 0x00;                                       
0131.00    memcpy(JOBINFO, argv[2], 26);                          
0132.00    JOBINFO[26] = 0x00;                                    
0133.00    sscanf(JOBINFO, "%10s%10s%6s", job, user, jobnbr);     
0134.00    memcpy(&SPLNO, argv[3], 4);                            
0135.00 }                                                         
0136.00 /****************/                                        
0137.00 void  INZSR(void)                                         
0138.00 /****************/                                        
0139.00 {                                                         
0140.00                                                           
0141.00    errcode.BYTESPRO = 160;                                
0142.00    errcode.BYTESAVL = 0;                                  
0143.00    memset(MSG, ' ', sizeof(MSG));                         
0144.00 }                                                                                        
0145.00 /*******************************************************/                                
0146.00 int   getSpoolattr(char* splf, char* jobinfo, int splno)                                 
0147.00 /*******************************************************/                                
0148.00 {                                                                                        
0149.00    Qdc_DEVD0600_t  devd0600;                                                             
0150.00    int  msg_data_len, len, iCode_Page, iGrph_Char_Set, bIGC = FALSE, esr, ccsid = FALSE; 
0151.00    int  CSCPL[4], su = 2, sel = 0;                                                       
0152.00    int  default_ccsid;                                                                   
0153.00    char jobID[16], splID[16], DEVD[11], Code_Page[11], Grph_Char_Set[11];                
0154.00    char JOBCCSID_For_CHRID[2];                                                           
0155.00 typedef struct {                                                                         
0156.00    short int status;                                                                     
0157.00    short int reason;                                                                     
0158.00    char reserved[8];                                                                     
0159.00 } FB;                                                                                    
0160.00 FB fb;                                                                                   
0161.00                                                                                          
0162.00    printf("* getSpoolattrn");                                                           
0163.00    memset(&splinfo, 0, sizeof(Qsp_SPLA0200_t));                                          
0164.00    memset(jobID, ' ', sizeof(jobID));                                                    
0165.00    memset(splID, ' ', sizeof(splID));                                                    
0166.00    QUSRSPLA((char*)&splinfo, sizeof(Qus_SPLA0200_t), "SPLA0200", jobinfo,                
0167.00                  jobID,  splID, splf, splno, (char*)&errcode);                           
0168.00    if(errcode.BYTESAVL != 0){/* APIERR */                                       
0169.00       memcpy(MSGID, errcode.MSGID, 7);                                          
0170.00       memset(MSGDTA, 0, sizeof(MSGDTA));                                        
0171.00       msg_data_len = errcode.BYTESAVL;                                          
0172.00       memcpy(MSGDTA, errcode.EXCPDATA, msg_data_len);                           
0173.00       return FALSE;                                                             
0174.00    }/* APIERR */                                                                
0175.00    memcpy(Code_Page, splinfo.spla0200.Code_Page, 10);                           
0176.00    Code_Page[10] = 0x00;                                                        
0177.00    printf("[%d] Code_Page = [%s]n", __LINE__, Code_Page);                      
0178.00    memcpy(Grph_Char_Set, splinfo.spla0200.Grph_Char_Set, 10);                   
0179.00    Grph_Char_Set[10] = 0x00;                                                    
0180.00    printf("[%d] Grph_Char_Set=[%s]n", __LINE__, Grph_Char_Set);                
0181.00    ccsid = splinfo.spla0200.CCSID;                                              
0182.00    printf("[%d] ccsid = %dn", __LINE__, ccsid);                                
0183.00    memcpy(JOBCCSID_For_CHRID, splinfo.spla0200.JOBCCSID_For_CHRID, 1);          
0184.00    printf("[%d] JOBCCSID_For_CHRID = 0x%02xn", __LINE__, JOBCCSID_For_CHRID);  
0185.00    if(strncmp(Code_Page, "*DEVD", 5) == 0){/*DEVD*/                             
0186.00      memcpy(DEVD, splinfo.spla0200.Job_Name, 10);                               
0187.00      DEVD[10] = 0x00;                                                           
0188.00      QDCRDEVD(&devd0600, sizeof(devd0600), "DEVD0600", DEVD, (char*)&errcode);  
0189.00      if(errcode.BYTESAVL != 0){/* APIERR */                                     
0190.00        memcpy(MSGID, errcode.MSGID, 7);                                         
0191.00        memset(MSGDTA, 0, sizeof(MSGDTA));                                       
0192.00        msg_data_len = errcode.BYTESAVL;                                           
0193.00        memcpy(MSGDTA, errcode.EXCPDATA, msg_data_len);                            
0194.00        return FALSE;                                                              
0195.00      }/* APIERR */                                                                
0196.00      iCode_Page     = devd0600.Char_ID_Code_Page;                                 
0197.00      iGrph_Char_Set = devd0600.Char_ID_Graphic_Char_Set;                          
0198.00      printf("language ID = %10.10sn", devd0600.DBCS_Feature_Language_ID);        
0199.00      printf("Last code point = %10.10sn", devd0600.DBCS_Feature_Last_Code_Point);
0200.00      printf("Matrix Size = %10.10sn", devd0600.DBCS_Feature_Matrix_Size);        
0201.00      if(strncmp(devd0600.Keyboard_Language_Type, "JKB", 3) == 0 ||  /*Japan*/     
0202.00         strncmp(devd0600.Keyboard_Language_Type, "KOB", 3) == 0 ||  /* Korea */   
0203.00         strncmp(devd0600.Keyboard_Language_Type, "RCB", 3) == 0 ||  /* CHS   */   
0204.00         strncmp(devd0600.Keyboard_Language_Type, "TAB", 3) == 0 ||  /* CHT   */   
0205.00         strncmp(devd0600.Keyboard_Language_Type, "THB", 3) == 0){/* 漢字 */       
0206.00         bIGC = TRUE;                                                              
0207.00      }/* 漢字 */                                                                  
0208.00      else bIGC = FALSE;                                                           
0209.00      if(devd0600.DBCS_Feature_RAM_Size > 0) bIGC = TRUE;                          
0210.00      else bIGC = FALSE;                                                           
0211.00      getchar();                                                                   
0212.00    }/*DEVD*/                                                                      
0213.00    else{/* その他 */                                                              
0214.00      iCode_Page = atoi(Code_Page);                                                
0215.00      iGrph_Char_Set = atoi(Grph_Char_Set);                                        
0216.00    }/* その他 */                                                                   
0217.00    if(strncmp(splinfo.spla0200.DBCS_Data, "*YES", 4) == 0) bIGC = 0x1301;          
0218.00    else bIGC = 0x1100;                                                             
0219.00    CCSID_of_Job = splinfo.spla0200.CCSID_of_Job;                                   
0220.00    printf("[%d] iGrph_Char_Set = %dn", __LINE__, iGrph_Char_Set);                 
0221.00    printf("[%d] iCode_Page     = %dn", __LINE__, iCode_Page);                     
0222.00    printf("[%d] bIGC           = %dn", __LINE__, bIGC);                           
0223.00    printf("[%d] CCSID_of_Job   = %dn", __LINE__, CCSID_of_Job);                   
0224.00    /*( CCSID の取得 )*/                                                            
0225.00    memset(&fb, 0, sizeof(FB));                                                     
0226.00    CSCPL[0] = iGrph_Char_Set;                                                      
0227.00    CSCPL[1] = iCode_Page;                                                          
0228.00    CSCPL[2] = 370;                                                                 
0229.00    CSCPL[3] = 300;                                                                 
0230.00    QTQSCSP(&CSCPL, &su, &bIGC, &ccsid, &esr, (void*)&fb);                          
0231.00    printf("[%d] QTQSCSP ccsid=%dn", __LINE__, ccsid);                             
0232.00    printf("[%d] QTQSCSP status=%d, reason=%dn", __LINE__, fb.status, fb.reason);  
0233.00    getchar();                                                                      
0234.00    QTQGRDC(&ccsid, &bIGC, &sel, &default_ccsid, &fb);                              
0235.00    printf("[%d] QTQGRDC ccsid=%dn", __LINE__, default_ccsid);                     
0236.00    printf("[%d] QTQGRDC status=%d, reason=%dn", __LINE__, fb.status, fb.reason);  
0237.00    getchar();                                                                      
0238.00    return ccsid;                                                                   
0239.00                                                                                    
0240.00    return UNKNOWN;                                                   
0241.00 }                                                                    
0242.00 /***************************/                                        
0243.00 char* getLanguage(int ccsid)                                         
0244.00 /***************************/                                        
0245.00 {                                                                    
0246.00    char LANG[14];                                                    
0247.00                                                                      
0248.00    switch(ccsid){/*switch*/                                          
0249.00    case  5026: case 5035: case 1399:                                 
0250.00       case 290: case 300: case 301: case 897: case 930: case 932:    
0251.00       case 942: case 1027: case 1041: case 4396: case 57345:         
0252.00                strcpy(LANG, " 日本語 "); break;                      
0253.00    case  37:   strcpy(LANG, " 英語 "); break;                        
0254.00    case 935: case 836: case 837: case 903: case 928: case 936:       
0255.00                 case 946: case 1042: case 1115: case 1380: case 1381:
0256.00                 strcpy(LANG, " 中国簡体字 "); break;                 
0257.00    case 937: case 835: case 904: case 927: case 938: case 948:       
0258.00                 case 950: case 1043: case 1114: case 28709:          
0259.00                 strcpy(LANG, " 中国繁体字 "); break;                 
0260.00    case 833: case 834: case 891: case 926: case 933: case 934:       
0261.00                 case 944: case 949: case 951: case 1040: case 1088:  
0262.00                strcpy(LANG, " 韓国語 "); break;                      
0263.00    default:    strcpy(LANG, " 不明 "); break;                        
0264.00    }/*switch*/  
0265.00    return LANG; 
0266.00 }    


            

[コンパイル]

CRTBNDC PGM(OBJLIB/CHKCCSID2) SRCFILE(SRCLIB/QCSRC2) DBGVIEW(*SOURCE) AUT(*ALL)

[解説]

重要なCCSIDの取得は

0224.00    /*( CCSID の取得 )*/                                                            
0225.00    memset(&fb, 0, sizeof(FB));                                                     
0226.00    CSCPL[0] = iGrph_Char_Set;                                                      
0227.00    CSCPL[1] = iCode_Page;                                                          
0228.00    CSCPL[2] = 370;                                                                 
0229.00    CSCPL[3] = 300;                                                                 
0230.00    QTQSCSP(&CSCPL, &su, &bIGC, &ccsid, &esr, (void*)&fb);  

である。CSCPLはスブールのグラフィック・コードとコードページの一組を
代入しているがその後は

0228.00    CSCPL[2] = 370;                                                                 
0229.00    CSCPL[3] = 300;

で強制的にプログラムで代入している。
最初のグラフィック・コードとコードページの一組だけでは
CCSIDを特定できないからである。
漢字のCCSID=5026, 5035の場合はこの370, 399の組合せでよいのだが
CCSID=1399の場合は 65535, 300である。
従って漢字であるからと言って 370, 300と決め付けて代入するわけにも
いかない。
1399とは区別がつかないからである。

スプールの漢字を識別するグラフィック・コードとコードページの組合せは
スプール属性のどこにも存在していない。
したがってスプールのCCSIDを一意的に特定することはできない。

0151.00    int  CSCPL[4], su = 2, sel = 0; 

で定義されているようにintの4個の配列でありsuはその個数をsu=2 で示している。
bIGC は ES 符号化形式 であって EBCDICでは次の種類しか定義されていない。

CCSID ES 符号化形式
37 0x1100
5026 0x1301
5035 0x1301
1399 0x1301

fb は

0155.00 typedef struct {                                                                         
0156.00    short int status;                                                                     
0157.00    short int reason;                                                                     
0158.00    char reserved[8];                                                                     
0159.00 } FB;                                                                                    
0160.00 FB fb;

と定義されていて結果のstatusと理由reasonを定義して

0236.00    printf("[%d] QTQGRDC status=%d, reason=%dn", __LINE__, fb.status, fb.reason); 

 のようにして結果と理由を示す。

 ここではAPI: QTQGRDC の使い方を示すと同時にスプールのCCSIDは
 APIを使ったとしてもスプールのグラフィック・コードとコードページからは
スプールのCCSIDを特定できないことを示した。