ここで紹介する技術は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 #include0016.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 UNKNOWn", __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("* getSpoolattrn"); 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 = %dn", __LINE__, ccsid); 0183.00 memcpy(JOBCCSID_For_CHRID, splinfo.spla0200.JOBCCSID_For_CHRID, 1); 0184.00 printf("[%d] JOBCCSID_For_CHRID = 0x%02xn", __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.10sn", devd0600.DBCS_Feature_Language_ID); 0199.00 printf("Last code point = %10.10sn", devd0600.DBCS_Feature_Last_Code_Point); 0200.00 printf("Matrix Size = %10.10sn", 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 = %dn", __LINE__, iGrph_Char_Set); 0221.00 printf("[%d] iCode_Page = %dn", __LINE__, iCode_Page); 0222.00 printf("[%d] bIGC = %dn", __LINE__, bIGC); 0223.00 printf("[%d] CCSID_of_Job = %dn", __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=%dn", __LINE__, ccsid); 0232.00 printf("[%d] QTQSCSP status=%d, reason=%dn", __LINE__, fb.status, fb.reason); 0233.00 getchar(); 0234.00 QTQGRDC(&ccsid, &bIGC, &sel, &default_ccsid, &fb); 0235.00 printf("[%d] QTQGRDC ccsid=%dn", __LINE__, default_ccsid); 0236.00 printf("[%d] QTQGRDC status=%d, reason=%dn", __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=%dn", __LINE__, fb.status, fb.reason);
のようにして結果と理由を示す。
ここではAPI: QTQGRDC の使い方を示すと同時にスプールのCCSIDは
APIを使ったとしてもスプールのグラフィック・コードとコードページからは
スプールのCCSIDを特定できないことを示した。