2010.01.08
Bruce Vining著

CLプログラムの文字ストリングの大文字変換

現在では、多国間環境でビジネスを行うのはごく当たり前になっています。これは、しばしばビジネスをサポートしているプログラムが、複数の国語に対応している必要があることも意味しています。文字ストリングを大文字変換できる機能により、プログラムをより簡単に複数の言語環境で動作させることができるようになります。Convert Case (QlgConvertCase) API により、文字ストリングの国語を心配することなく、アルファベット文字ストリングを大文字変換 (つまりすべて大文字かすべて小文字) に変換できます。この大文字変換機能を CL プログラムに追加できる 2 つのコマンドを Convert Case API に基づいて作成しました。では、コマンド UPPERCASE および LOWERCASE とそのパラメーター、つまり Convert Case API 自体またコマンド処理プログラム (CPP) のパラメーターとコマンド使用例についてお話してゆきましょう。(マシン・インターフェース命令を使用した代替技法、またそれが文字ストリングの大文字変換の最適な方法でない理由については、下記サイドバーの「The Problem with TESTRPL and Monocasing」をご覧ください。)

UPPERCASE コマンドと LOWERCASE コマンド 最初に、2 つの大文字変換コマンドを定義してから、Convert Case API 構造について詳しく見てゆきましょう。コマンドの名前は UPPERCASE と LOWERCASE で、これら 2 つのコマンドのコマンド・ソースはそれぞれ図 1 の A と B に示しています。C にあるのは、2 つのコマンドのプロンプト・テキストを含むメッセージ・ファイル USERMSGF を作成するコマンドで、D にあるのは、適切なメッセージ記述を USERMSGF に追加するコマンドです。E のコマンドは UPPERCASE コマンドおよび LOWERCASE コマンドを作成します。CPP はまだ存在していませんが、コマンドは正常に作成されます。図 1 で、提供されたコマンドで VINING というライブラリー名を使用している点に注意してください。読者は、より自分のシステムに合ったライブラリー名を使用するはずです。

両方のコマンドは 3 つのパラメーターを定義します。最初のパラメーター String は、大文字または小文字のいずれかを指定する文字ストリング変数を表しています。このパラメーターは定義済み RTNVAL(*YES) であるため、パラメーターは (定数と違って) 変数でなければならず、この変数は大文字または小文字にする文字ストリングを渡し、正しく大/小文字指定された値を戻すのに使用されます。LEN(1) キーワードは、String 変数が最低でも 1 バイトでなければならないことを示します。VARY(*YES *INT4) 指定により、文字変数の実 (または宣言) サイズは、パラメーターが CPP に渡されるときに、文字変数の値より前に来ます。このサイズは、4 バイト整数値としてフォーマットされます。MIN(1) 要件は、String パラメーターの指定が必要であることを示します。

2 番目のパラメーター CCSID は、大/小文字指定する文字ストリングの CCSID を示します。このパラメーターはオプションで、指定しない場合はデフォルトで *JOB (現在のデフォルト・ジョブ CCSID) になります。このパラメーターは 4 バイト整数値として定義されます。(明示的またはデフォルトで) *JOB を使用する場合、SPCVAL((*JOB 0)) 属性があるため CPP には実際には値 0 が渡されます。このパラメーターは、CL 開発者が SEU などのエディターを使用するときに F9 (すべてのパラメーター) または F10 (追加パラメーター) を使用しない限り、プロンプト表示されません。

3 番目のパラメーター Direction は、CONSTANT キーワードが指定されているため、プロンプト表示されない非表示パラメーターです。 気が付かなかったかもしれませんが、UPPERCASE コマンドと LOWERCASE コマンドを作成したとき、図 1 の E でおわかりのように、両方のコマンドに同じ CPP、CASEAPI を使用しました。非表示 Direction パラメーターは、実際に開発者がどのコマンドを使用したかを CPP に通知する場合に使用します。UPPERCASE コマンドを使用している場合、4 バイト整数値 0 が CPP に渡されます。LOWERCASE コマンドを使用している場合、4 バイト整数値 1 が渡されます。CPP は Convert Case API を呼び出すときにこの情報を使用します。例えば、大文字には *CHAR 1 の 'U'、小文字には 'L' など任意のタイプの非表示パラメーターを使用することもできたかもしれませんが、CPP を検査するときは、これら特定の値を選択する理由 (主に CPP でのコーディングの削減) が存在することがおわかりでしょう。

Convert Case API

Convert Case API は CCSID を区別する大/小文字変換を行い、大文字または小文字いずれかの変換をサポートします。
http://publib.boulder.ibm.com/infocenter/iseries/v5r4/topic/
apis/QLGCNVC....
 
図 2 にある API 文書に API のパラメーター・リストが記載されていることがわかると思います。

最初のパラメーター Request 制御ブロックは、実行する大/小文字の種類を定義する可変長構造です。API はいくつかの種類の要求をサポートしていますが、最も柔軟 (かつ、唯一お勧めする) のがタイプ 1、CCSID ベースの大/小文字指定です。図 3 は、CCSID ベース・サポートを使用した場合の要求制御ブロックの定義を示しています。

最初のフィールド Type of request は、使用する大/小文字指定の種類を定義しています。われわれの場合は、常に値 1、CCSID ベース大/小文字指定になります。2 番目のフィールド CCSID of input data は、入力 (および出力) 文字データの CCSID を指定します。1 つ特殊値 0 が定義されており、文字データがジョブのデフォルト CCSID を示しています。リマインダーとして、UPPERCASE および LOWERCASE コマンド定義で CCSID パラメーターの特殊値 *JOB を値 0 にマップします。

3 番目のフィールド Case request は、実行する大/小文字変換のタイプを指定します。値 0 は API が入力文字ストリングを大文字にし、値 1 は API が入力文字ストリングを小文字にすることを示します。これらはそれぞれ、UPPERCASE および LOWERCASE のコマンド定義で使用された値であることを思い出すでしょう。4 番目のフィールド Reserved は予約フィールドで x'00' に設定する必要があります。

図 2 のパラメーター・リストに戻って、2 番目のパラメーターは変換または大/小文字にする入力文字ストリングです。3 番目のパラメーターは変換後の入力文字ストリングです。4 番目のパラメーターは、入力文字ストリングの長さで、5 番目のパラメーターは標準 API エラー・コードです。

CASEAPI CPP

では 2 つのコマンドの CPP を見てみましょう。図 4 は CPP のソース CASEAPI を示しています。次のコマンドを使用してソースをコンパイルできます。

CRTBNDCL PGM(CASEAPI)

プログラムはまず CPP に渡される 3 つのパラメーターを定義します。これらのパラメーターは &String、&CCSID、および &Direction で、それぞれ 3 つのコマンド・パラメーター・キーワード String、CCSID、および Direction に対応しています。

2 番目と 3 番目のパラメーターは一目瞭然です。最初のパラメーター &String は、図 4 の A に 2 つのサブフィールドがあるデータ構造として定義されています。&String の最初のサブフィールド &Len は4 バイト整数として定義され、呼び出し側プログラムの文字変数の宣言サイズを表しています。UPPERCASE および LOWERCASE コマンド定義に RTNVAL(*YES) が指定されているため、システムはこのサイズ値を CPP に提供します。2 番目のサブフィールド &Str は、呼び出し側プログラムの入力文字ストリングの実値です。CASEAPI 内の &String パラメーターの長さ定義は任意です。ただし、4 バイトの &Len サブフィールドと少なくとも 1 バイトの &Str サブフィールドを指定するのに少なくとも 5 バイトが必要です。コマンド分析プログラムを考慮しているため、V5R4 における &Str の実際の最大サイズは 3000 バイトです。CPP から戻ったときに、&Str サブフィールドには元の文字ストリングが変換された値が入っています。この戻り値は、システムにより呼び出し側プログラムの文字変数に移動されます。

図 4 の B では、Request 制御ブロック自体 &Rqs_Block とともに Convert Case API の Request 制御ブロック構造のサイズ &Rqs_Size が定義されています。Request 制御ブロックのフォーマットの中には 22 バイトより大きなものがありますが、CCSID ベースのフォーマットは正確に 22 バイトで、CASEAPI プログラムはこの特定のフォーマットのみ定義しています。(各種 &Rqs_Block サブフィールドの意味について詳しくは、前のセクション「Convert Case API」を参照してください。)

B に続き、プログラムは API エラー・コード構造を単一整数値として宣言しています。この整数は、エラー・コード構造の Bytes 提供フィールドに対応しています。このフィールドを 0 に初期化すると Convert Case API がエラー条件をエスケープ・メッセージとして戻します。

C で、プログラムは Request 制御ブロック変数 &Rqs_Block をすべて x'00' に初期化します。これは、Reserved サブフィールド &Reserved が正しく設定されていることを確認するために行います。

D で、プログラムは Request 制御ブロックのサブフィールドの正しい値を設定しています。&Rqs_Type は CCSID ベース変換を示す 1 に設定され、&Rqs_CCSID はコマンドで (またはデフォルトで) 指定された CCSID に設定され、&Rqs_Dir は、コマンドの非表示パラメーター値を使用して 0 (大文字) または 1 (小文字) に設定されています。基礎となる API 値をコマンドの非表示パラメーターとして使用することで、次のような追加コードを実行する必要がなくなります。

IF COND(&DIRECTION *EQ 'U') THEN  +
 (CHGVAR VAR(&RQS_DIR) VALUE(0))

Convert Case API が呼び出され、CPP は呼び出し側プログラムに戻ります。&String パラメーターの &Str サブフィールドは Convert Case API の Input データ・パラメーターと Output データ・パラメーターの両方に使用されています。データ・パラメーターの Length は &Len サブフィールドに設定されています。おわかりのように、CASEAPI CPP は極めて分かりやすくなっています。

コマンドのテスト

図 5 に CASETEST という名前のテスト・ケースのソースを記載しています。プログラムのコンパイルには、次のコマンドを使用します。

CRTBNDCL PGM(CASETEST)

プログラムは 50 バイトの文字変数 &Char を宣言し、値 'Beckie Nunez' に初期化します。プログラムは UPPERCASE コマンドを使用して &Char を大文字に変換し、結果 BECKIE NUNEZ を表示します。次に、CASETEST は LOWERCASE コマンドを使用して &Char (現在は 'BECKIE NUNEZ') を変換し、新しい結果 beckie nunez を表示します。

同じコマンドおよび CPPが他の言語環境で動作します。例えば、ギリシャ語の環境 (CCSID 875) では名前 Ελενη (Helene、Helena、または Helen) は最初に ΕΛΕΝΗ と表示され、次に ελενη と表示されます。次の日には会社でギリシャ語の名前を扱わないかもしれませんが、あなたの方で作り直すことなく、そうした新しい環境に対してプログラムが準備できているのは悪くありません。

Bruce Vining (Bruce@BruceVining.com) : 米国ミネソタ州ロチェスターに拠点を置くコンサルティングおよび契約プログラミング会社である Bruce Vining Services の代表取締役および共同設立者。IBM に 27 年間勤務。IBM S/38 から始まり、ごく最近は IBM System i を担当。.V2R3 から V6R1 の IBM Design Control for System API を担当していただけでなく、グローバリゼーションおよびソフトウェア保守容易性などの分野で i5/OS 設計の責任者でもあった。

ページトップ

ボタン