印刷スプール・ファイルには 実は CCSID という値が登録はされていない。
CCSID とは、
・グラフィック文字コード と コード・ページとの組み合わせ
を代表する番号のことである。
多くはコード・ページが CCSID を表しているのだが、厳密には
グラフィック文字コードも考慮に入れなければならない。
この組み合わせは莫大な数になってしまうので CCSID で代表してしまうように
なっているのである。
印刷スプールでは、CCSID の登録はなく、
で判断できるかというとそうとも言い切れない。
何やら歯切れの悪い説明になってしまっているが、印刷スプールの CCSID は
扱いにくいのである。
しかし、この印刷スプールが日本語を出力したものか、中国語(簡体字/繁体字)を
出力したものか判断を迫られることは今後、その機会が増えてくるだろう。
なぜなら今や、多くの国内企業は工場などの生産拠点を海外に持ち、
国際言語の処理も珍しくはなくなっているからである。
そこで 印刷スプールに含まれるCCSID の情報を探してみると、
①ユーザー・データの CCSID ....................... | 印刷スプールにユーザーが定義できる10文字のテキストのCCSID |
②実行ジョブの CCSID .................................... | 印刷スプールを出力したとき実行されたジョブの CCSID |
③印刷装置ファイルの CCSID ...................... | 印刷スプールを保有している印刷装置ファイル( PRTF ) のCCSID |
などが見つかる。
これらの情報は DSPSPLF コマンドや WRKOUTQ コマンドでは調べることはできない。
ただし③の PRTF だけは可能である。
海外製品では②を持って印刷スプールの CCSID と判断する、というのもあるが、それは乱暴である。
なぜなら日本語環境で中国語のデータ・ベースを QUERY で印刷出力した印刷スプールは
日本語環境として登録されているはずだからである。
前置きが長くなったが、それでもやはりスプールの CCSID を調べたい、という要求はある。
ここでは次のようにして印刷スプールの CCSID をある程度、調べてくれるコマンド: CHKCCSID
を
紹介する。
例えば印刷装置ファイルが次のような2次言語ライブラリーに所属しているのであれば
CCSID を判断することができる。
2次言語ライブラリー | 意味 | CCSID |
---|---|---|
QSYS2989 QSYS2987 QSYS2986 |
中国語(簡体字) DBCS (PRC) 中国語(繁体字) DBCS 韓国語 |
935 937 833 |
その次の判定材料は「②実行ジョブの CCSID」である。
次に「③印刷装置ファイルの CCSID」も判定材料にしたいところであるが
ほとんどの印刷装置ファイルの CCSIDは コード化文字セット ID(CCSID) が 0 として作成されているので
判断材料として利用することができない。
次にコンテンツ、つまり印刷スプールの内容にしても着目してみよう。
印刷スプールに使われている漢字または全角文字が、その言語独自のものであれば言語を
推測できるかもしれない。
私たちはこの方法で数多くの印刷スプール内に含まれている文字コードを調べてみたが
多くの文字コードが、これらの言語で共通して使われているため言語の特定に至ることはできなかった。
コマンド : CHKCCSID
は、完全ではないが印刷スプールの CCSID 、とりわけ言語を簡単に知ることができ、
国際言語を判断するには十分に社内で役に立っている。
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
CRTCMD CMD(MYLIB/CHKCCSID) PGM(MYLIB/CHKCCSIDCL) SRCFILE(MYSRCLIB/QCMDSRC) AUT(*ALL)
0001.00 PGM PARM(&SPLF &JOBINFO &SPLNO) 0002.00 /*---------------------------------------------------------*/ 0003.00 /* CHKCCSIDCL : CCSID 検査 */ 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/CHKCCSID) 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(MYLIB/CHKCCSIDCL) SRCFILE(MYSRCLIB/QCLSRC) AUT(*ALL)
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 R540SRC/QCSRC */ 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 <stdio.h> 0016.00 #include <stdlib.h> 0017.00 #include <string.h> 0018.00 #include <micomput.h> /* triml */ 0019.00 #include <signal.h> 0020.00 #include <errno.h> 0021.00 #include "asnet.src/h(QUSRSPLA)" /* V5R2M0-V6R1M0 共通 */ 0022.00 #include <QUSGEN.h> 0023.00 #include <QTQUSF.h> /* QtqValidateCCSID */ 0024.00 0025.00 #define TRUE 0 0026.00 #define FALSE -1 0027.00 #define UNKNOWN -2 0028.00 #define MAX_HEAP_SIZE 16711600 /* 高速ヒープ・サイズ 16MB*/ 0029.00 #define TERA_HEAP_SIZE 214748324 /* 高速ヒープ・サイズ 2GB */ 0030.00 #define MAX_USRSPACE 16776704 0031.00 #define JAPAN 1399 0032.00 #define CHINA 935 0033.00 #define HONGKONG 937 0034.00 #define KOREA 933 0035.00 #define USA 37 0036.00 volatile _INTRPT_Hndlr_Parms_T ca; 0037.00 typedef struct { 0038.00 int BYTESPRO; 0039.00 int BYTESAVL; 0040.00 char MSGID[7]; 0041.00 char RESRVD; 0042.00 char EXCPDATA[132]; 0043.00 } ERRSTRUCTURE; /* Define the error return structure */ 0044.00 ERRSTRUCTURE errcode;/* Error Code Structure for RCVMSG */ 0045.00 typedef struct { 0046.00 char NM[10]; 0047.00 char LIB[10]; 0048.00 } QNAME; /* Define the qualified name */ 0049.00 QNAME inname; /* Qualified user space name */ 0050.00 char os400[6]; /* OS/400 バージョン */ 0051.00 /*************************************************************/ 0052.00 /* 内 部 使 用 関 数 */ 0053.00 /*************************************************************/ 0054.00 void GetParam(int argc, char *argv[]); 0055.00 void INZSR(void); 0056.00 int getSpoolattr(char* splf, char* jobinfo, int splno); 0057.00 char* getLanguage(int ccsid); 0058.00 /*************************************************************/ 0059.00 /* IMPORT 関 数 */ 0060.00 /*************************************************************/ 0061.00 /*************************************************************/ 0062.00 /* IMPORT 変 数 */ 0063.00 /*************************************************************/ 0064.00 /*************************************************************/ 0065.00 /* 外 部 呼 出 し 関 数 */ 0066.00 /*************************************************************/ 0067.00 /*************************************************************/ 0068.00 /* グ ロ ー バ ル 変 数 */ 0069.00 /*************************************************************/ 0070.00 /*------( 受取りパラメータ値 )----------*/ 0071.00 char SPLF[11], JOBINFO[27], MSGID[8], MSG[133], MSGDTA[133]; 0072.00 int SPLNO; 0073.00 /*------( 受取りパラメータ値 )----------*/ 0074.00 char job[11], user[11], jobnbr[7], LANG[14]; 0075.00 int get_ccsid, Spooled_File_Size, job_ccsid, txt_ccsid; 0076.00 char DBCS_SOSI[10], WHY[48]; 0077.00 typedef struct { 0078.00 Qus_SPLA0200_t spla0200; 0079.00 char Options[20]; 0080.00 } Qsp_SPLA0200_t; 0081.00 Qsp_SPLA0200_t splinfo; 0082.00 long spl_size; /* スプール・バッファー・サイズ */ 0083.00 char* spool_buf; 0084.00 int chk_table[4], CCSID_of_Job; 0085.00 char Dev_File_Lib[11], Dev_File_Name[11]; 0086.00 /********************************************************************/ 0087.00 /* m a i n --- main module of this pgm */ 0088.00 /* */ 0089.00 /* <PARAMETER> 1. SPLF */ 0090.00 /* 2. JONINFO */ 0091.00 /* 3. SPLNO */ 0092.00 /* 4. MSGID */ 0093.00 /* 5. MSG */ 0094.00 /* 6. MSGDTA */ 0095.00 /* */ 0096.00 /*------------------------------------------------------------------*/ 0097.00 0098.00 int main(int argc, char *argv[]){ 0099.00 int ccsid, rc; 0100.00 0101.00 #pragma exception_handler(MONMSG, ca, 0, _C2_MH_ESCAPE, 0102.00 _CTLA_HANDLE) 0103.00 GetParam(argc, argv); /*[ パラメータの取得 ]*/ 0104.00 INZSR(); /*[ 初期設定 ]*/ 0105.00 0106.00 if((ccsid = getSpoolattr(SPLF, JOBINFO, SPLNO)) == FALSE){/* 実行 0107.00 memcpy(argv[4], MSGID, 7); 0108.00 memcpy(argv[5], MSG, 132); 0109.00 memcpy(argv[6], MSGDTA, 132); 0110.00 exit(-1); 0111.00 }/* 実行 JOB */ 0112.00 if(ccsid == UNKNOWN){/* 装置 */ 0113.00 if(strncmp(Dev_File_Lib, "QSYS2989", 8) == 0){/* CHINA */ 0114.00 ccsid = get_ccsid = CHINA; 0115.00 sprintf(WHY, "DEV_NAME=%s/%s", Dev_File_Lib, Dev_File_Name); 0116.00 }/* CHINA */ 0117.00 else if(strncmp(Dev_File_Lib, "QSYS2987", 8) == 0){/* HONGKONG */ 0118.00 ccsid = get_ccsid = HONGKONG; 0119.00 sprintf(WHY, "DEV_NAME=%s/%s", Dev_File_Lib, Dev_File_Name); 0120.00 }/* HONGJONG */ 0121.00 else if(strncmp(Dev_File_Lib, "QSYS2986", 8) == 0){/* KOREA */ 0122.00 ccsid = get_ccsid = KOREA; 0123.00 strcpy(WHY, "DEV_NAME"); 0124.00 }/* KOREA */ 0125.00 else if(strncmp(Dev_File_Lib, "QSYS2930", 8) == 0){/* JAPAN */ 0126.00 ccsid = get_ccsid = JAPAN; 0127.00 sprintf(WHY, "DEV_NAME=%s/%s", Dev_File_Lib, Dev_File_Name); 0128.00 }/* JAPAN */ 0129.00 else if(strncmp(Dev_File_Lib, "QSYS2924", 8) == 0){/* ENGLISH */ 0130.00 ccsid = get_ccsid = USA; 0131.00 sprintf(WHY, "DEV_NAME=%s/%s", Dev_File_Lib, Dev_File_Name); 0132.00 }/* ENGLISH */ 0133.00 else if(strncmp(Dev_File_Lib, "QSYS2984", 8) == 0){/* ENGLISH */ 0134.00 ccsid = get_ccsid = USA; 0135.00 sprintf(WHY, "DEV_NAME=%s/%s", Dev_File_Lib, Dev_File_Name); 0136.00 }/* ENGLISH */ 0137.00 }/* 装置 */ 0138.00 if(ccsid == UNKNOWN){/* job_ccsid */ 0139.00 get_ccsid = CCSID_of_Job; 0140.00 switch(CCSID_of_Job){/*switch*/ 0141.00 case 5026: case 5035: case 1399: 0142.00 ccsid = CCSID_of_Job; /* 日本語 */ 0143.00 sprintf(WHY, "CCSID_OF_JOB=%d", ccsid); 0144.00 break; 0145.00 case 290: case 300: case 301: case 897: case 930: case 932: 0146.00 case 942: case 1027: case 1041: case 4396: case 57345: 0147.00 ccsid = CCSID_of_Job; /* 日本語 */ 0148.00 sprintf(WHY, "CCSID_OF_JOB=%d", ccsid); 0149.00 break; 0150.00 case 935: case 836: case 837: case 903: case 928: case 936: 0151.00 case 946: case 1042: case 1115: case 1380: case 1381: 0152.00 ccsid = CCSID_of_Job; /* 中国語 ( 簡体字 )*/ 0153.00 sprintf(WHY, "CCSID_OF_JOB=%d", ccsid); 0154.00 break; 0155.00 case 937: case 835: case 904: case 927: case 938: case 948: 0156.00 case 950: case 1043: case 1114: case 28709: 0157.00 ccsid = CCSID_of_Job; /* 中国語 ( 繁体字 )*/ 0158.00 sprintf(WHY, "CCSID_OF_JOB=%d", ccsid); 0159.00 break; 0160.00 case 833: case 834: case 891: case 926: case 933: case 934: 0161.00 case 944: case 949: case 951: case 1040: case 1088: 0162.00 ccsid = CCSID_of_Job; /* 韓国語 */ 0163.00 sprintf(WHY, "CCSID_OF_JOB=%d", ccsid); 0164.00 break; 0165.00 default: 0166.00 get_ccsid = CCSID_of_Job; 0167.00 sprintf(WHY, "CCSID_OF_JOB=%d", get_ccsid); 0168.00 break; 0169.00 }/*switch*/ 0170.00 }/* job_ccsid */ 0171.00 if((rc = QtqValidateCCSID(get_ccsid)) > 0){/* 成功 */ 0172.00 }/* 成功 */ 0173.00 else{/* 失敗 */ 0174.00 switch(rc){/*switch*/ 0175.00 case 0: 0176.00 sprintf(MSG, "CCSID %d は CDRA の特別な目的用です。 (%s)",get_ccs 0177.00 case -1: 0178.00 sprintf(MSG, "CCSID %d はシステムで認められていません (%s)", get_cc 0179.00 break; 0180.00 case -2: 0181.00 sprintf(MSG, "CCSID %d は 1-65535 の範囲外です。 (%s)", get_ccs 0182.00 break; 0183.00 default: break; 0184.00 }/*switch*/ 0185.00 memcpy(argv[4], " ", 7); 0186.00 memcpy(argv[5], MSG, 132); 0187.00 return; 0188.00 }/* 失敗 */ 0189.00 if(ccsid == UNKNOWN){/* 不明 */ 0190.00 sprintf(MSG, " 不明な CCSID %d を特定できません。 (%s)", get_ccsi 0191.00 memcpy(argv[5], MSG, 132); 0192.00 exit(-1); 0193.00 }/* 不明 */ 0194.00 strcpy(LANG, getLanguage(ccsid)); 0195.00 sprintf(MSG, "CCSID は %d, 言語は %s です。 (%s)", ccsid, LANG, WHY 0196.00 memcpy(argv[4], " ", 7); 0197.00 memcpy(argv[5], MSG, 132); 0198.00 return; 0199.00 0200.00 MONMSG: 0201.00 #pragma disable_handler 0202.00 exit(0); 0203.00 } 0204.00 /*************************************/ 0205.00 void GetParam(int argc, char *argv[]) 0206.00 /*************************************/ 0207.00 { 0208.00 memcpy(SPLF, argv[1], 10); 0209.00 SPLF[10] = 0x00; 0210.00 memcpy(JOBINFO, argv[2], 26); 0211.00 JOBINFO[26] = 0x00; 0212.00 sscanf(JOBINFO, "%10s%10s%6s", job, user, jobnbr); 0213.00 memcpy(&SPLNO, argv[3], 4); 0214.00 } 0215.00 /****************/ 0216.00 void INZSR(void) 0217.00 /****************/ 0218.00 { 0219.00 0220.00 errcode.BYTESPRO = 160; 0221.00 errcode.BYTESAVL = 0; 0222.00 memset(MSG, ' ', sizeof(MSG)); 0223.00 } 0224.00 /*******************************************************/ 0225.00 int getSpoolattr(char* splf, char* jobinfo, int splno) 0226.00 /*******************************************************/ 0227.00 { 0228.00 int msg_data_len, len; 0229.00 char jobID[16], splID[16], Code_Page[11]; 0230.00 0231.00 memset(&splinfo, 0, sizeof(Qsp_SPLA0200_t)); 0232.00 memset(jobID, ' ', sizeof(jobID)); 0233.00 memset(splID, ' ', sizeof(splID)); 0234.00 QUSRSPLA((char*)&splinfo, sizeof(Qus_SPLA0200_t), "SPLA0200", 0235.00 jobinfo, 0236.00 jobID, splID, splf, splno, (char*)&errcode); 0237.00 if(errcode.BYTESAVL != 0){/* APIERR */ 0238.00 memcpy(MSGID, errcode.MSGID, 7); 0239.00 memset(MSGDTA, 0, sizeof(MSGDTA)); 0240.00 msg_data_len = errcode.BYTESAVL; 0241.00 memcpy(MSGDTA, errcode.EXCPDATA, msg_data_len); 0242.00 return FALSE; 0243.00 }/* APIERR */ 0244.00 memcpy(Code_Page, splinfo.spla0200.Code_Page, 10); 0245.00 if(strncmp(Code_Page, "*DEVD", 5) == 0){/*DEVD*/ 0246.00 memcpy(Dev_File_Lib, splinfo.spla0200.Dev_File_Lib, 10); 0247.00 Dev_File_Lib[10] = 0x00; 0248.00 memcpy(Dev_File_Name, splinfo.spla0200.Dev_File_Name, 10); 0249.00 Dev_File_Name[10] = 0x00; 0250.00 }/*DEVD*/ 0251.00 CCSID_of_Job = splinfo.spla0200.CCSID_of_Job; 0252.00 0253.00 return UNKNOWN; 0254.00 } 0255.00 /***************************/ 0256.00 char* getLanguage(int ccsid) 0257.00 /***************************/ 0258.00 { 0259.00 char LANG[14]; 0260.00 0261.00 switch(ccsid){/*switch*/ 0262.00 case 5026: case 5035: case 1399: 0263.00 case 290: case 300: case 301: case 897: case 930: case 932: 0264.00 case 942: case 1027: case 1041: case 4396: case 57345: 0265.00 strcpy(LANG, " 日本語 "); break; 0266.00 case 37: strcpy(LANG, " 英語 "); break; 0267.00 case 935: case 836: case 837: case 903: case 928: case 936: 0268.00 case 946: case 1042: case 1115: case 1380: case 1381: 0269.00 strcpy(LANG, " 中国簡体字 "); break; 0270.00 case 937: case 835: case 904: case 927: case 938: case 948: 0271.00 case 950: case 1043: case 1114: case 28709: 0272.00 strcpy(LANG, " 中国繁体字 "); break; 0273.00 case 833: case 834: case 891: case 926: case 933: case 934: 0274.00 case 944: case 949: case 951: case 1040: case 1088: 0275.00 strcpy(LANG, " 韓国語 "); break; 0276.00 default: strcpy(LANG, " 不明 "); break; 0277.00 }/*switch*/ 0278.00 return LANG; 0279.00 }
CRTBNDC PGM(MYLIB/CHKCCSID) SRCFILE(MYSRCLIB/QCSRC) AUT(*ALL)
API : QtqValidateCCSID は、指定した CCSID がこのシステムで有効であるかどうか検査するための
API である。例えば中国語の印刷スプールの CCSID : 935 が見つかったとしても
中国語がシステムに二次言語として導入されていなければ API : QtqValidateCCSID はエラーを戻す。
CHKCCSID
+ F4キーを押して、次のように印刷スプールを指定する。
CCSID の結果と、その判断になった理由が併せて表示される。