EBCDICからASCIIへの変換の注意点
OpenFrameを使用してメインフレーム・システムからオープン・システム環境にリソースを移行するには、リソースをEBCDICからASCIIに変換する必要があります。
EBCDICデータをASCIIデータに変換するときにさまざまな問題が発生しますが、特に、COBOLで作成したアプリケーション・プログラムのソース・ファイルを変換する際に発生する場合が多いです。以下は、ソース・ファイルの変換時に発生する問題のうち、深刻度の高い3つの問題について説明します。
-
16進数値の処理
-
文字ソート順の処理
-
2バイト・スペースの処理
本節では、例を挙げて問題の原因や対処方法について説明します。
1. 16進数値の処理
以下は、16進数値を使用して作成されたロジックが含まれたCOBOLソース・プログラムをdsmiginツールを使用してASCIIに変換する例です。
01 WORK06-AREA. 05 W06-KOUZA-NO. 10 FILLER PIC X(01) VALUE X'F1'. 10 W06-NO-1 PIC X(01). 10 FILLER PIC X(01) VALUE X'F2'. 10 W06-NO-2 PIC X(01). 10 FILLER PIC X(01) VALUE X'F3'. 10 W06-NO-3 PIC X(01). 10 FILLER PIC X(01) VALUE X'F4'. 10 W06-NO-4 PIC X(01). 10 FILLER PIC X(01) VALUE X'F5'. 10 W06-NO-5 PIC X(01). 10 FILLER PIC X(01) VALUE X'F6'. 10 W06-NO-6 PIC X(01). 10 FILLER PIC X(01) VALUE X'F7'. 10 W06-NO-7 PIC X(01).
上記のファイルは、COBOLで作成されたソース・ファイルを、一般的な変換方法を使用してEBCDIC文字をASCII文字に変換した状態を示しています。上記のファイルは、変換が正常に完了されたかのように見えますが、以下のような問題が含まれている可能性があります。
以下は、上記例の一部を示しています。
10 FILLER PIC X(01) VALUE X'F1'.
上記の行では、EBCDIC文字がASCII文字に正常に変換されていますが、EBCDICで作成されたCOBOLプログラムに実装された業務ロジックは正常に変換されていない可能性があります。
たとえば、ソース・ファイルでX’F1’がF1という文字を表すのではなく、X’F1’が指すEBCDIC値の1であると想定します。一般的な文字セットの変換プロセスではEBCDIC値の1を処理できないため、その値を手動で変更する必要があります。ソース・ファイルをASCIIに変換した後、以下のようにASCII値の1に該当する値の31にソースを修正します。
10 FILLER PIC X(01) VALUE X'31'.
以下は、dsmiginツールを使用して上記の最初のサンプル・ファイルと同じソース・ファイルをASCIIに変換した後、文字を数値に変換した例です。
01 WORK06-AREA. 05 W06-KOUZA-NO. 10 FILLER PIC X(01) VALUE X '31'. 10 W06-NO-1 PIC X(01). 10 FILLER PIC X(01) VALUE X '32'. 10 W06-NO-2 PIC X(01). 10 FILLER PIC X(01) VALUE X '33'. 10 W06-NO-3 PIC X(01). 10 FILLER PIC X(01) VALUE X '34'. 10 W06-NO-4 PIC X(01). 10 FILLER PIC X(01) VALUE X '35'. 10 W06-NO-5 PIC X(01). 10 FILLER PIC X(01) VALUE X '36'. 10 W06-NO-6 PIC X(01). 10 FILLER PIC X(01) VALUE X '37'. 10 W06-NO-7 PIC X(01).
16進数値の処理時に発生する問題は、プログラムに16進数値が直接記述されており、文字を変換する際に問題が発生するのが一般的ですが、その逆の場合もあります。
01 YEAR-TABLE. 05 FILLER PIC X(12) VALUE '{{{{{{JJJJJJ'. 05 FILLER PIC X(12) VALUE '{{{{{{{JJJJJ'. 05 FILLER PIC X(12) VALUE '{{{{{{{{JJJJ'. 05 FILLER PIC X(12) VALUE '{{{{{{{{{JJJ'. 05 FILLER PIC X(12) VALUE '{{{{{{{{{{JJ'. 05 FILLER PIC X(12) VALUE '{{{{{{{{{{{J'. 05 FILLER PIC X(12) VALUE '{{{{{{{{{{{{'. 05 FILLER PIC X(12) VALUE 'A{{{{{{{{{{{'. 05 FILLER PIC X(12) VALUE 'AA{{{{{{{{{{'. 05 FILLER PIC X(12) VALUE 'AAA{{{{{{{{{'. 05 FILLER PIC X(12) VALUE 'AAAA{{{{{{{{'. 05 FILLER PIC X(12) VALUE 'AAAAA{{{{{{{'.
上記の例で「{」という文字は、プログラム・ロジックで文字として使用されたのではなく、「{」文字の16進数値に該当するX’C0’文字が指すZD(ゾーン10進数)値を意味します。
この場合は、メインフレームのZD値X’C0’に該当するASCIIのZD値はX’30’であるため、X’30’に該当するASCII文字の0に変更すると、ユーザー・アプリケーションを正常に変換できます。ただし、EBCDICソース・データをASCIIデータに変換した後にソースを修正することをお勧めします。
01 YEAR-TABLE. 05 FILLER PIC X(12) VALUE '000000qqqqqq'. 05 FILLER PIC X(12) VALUE '0000000qqqqq'. 05 FILLER PIC X(12) VALUE '00000000qqqq'. 05 FILLER PIC X(12) VALUE '000000000qqq'. 05 FILLER PIC X(12) VALUE '0000000000qq'. 05 FILLER PIC X(12) VALUE '00000000000q'. 05 FILLER PIC X(12) VALUE '000000000000'. 05 FILLER PIC X(12) VALUE '100000000000'. 05 FILLER PIC X(12) VALUE '110000000000'. 05 FILLER PIC X(12) VALUE '111000000000'. 05 FILLER PIC X(12) VALUE '111100000000'. 05 FILLER PIC X(12) VALUE '111110000000'.
前述した16進数値の処理問題は、ユーザーが作成したプログラム・ソースの16進数値を意味するのか、その値が示すEBCDIC文字(または、逆の場合も該当する)を意味するのかが、文字セットの変換プロセスでは区別できません。
ソース・ファイルの16進数値を把握するには、COBOLで作成されたプログラム・ソースはCOBOL文法を、BMSマップの場合はBMSマクロ文法を適用して分析する必要があります。
現在は、この問題を解決するためにTmaxSoftのコンサルタントが移行に直接参加してソース・ファイルを分析しています。今後、プログラム単位で自動的に分析できるツールを開発する予定です。 |
2. 文字ソート順の処理
EBCDIC文字をASCII文字に変換したとき、文字変換に問題がないように見える場合でも、各文字セットの固有の特性により、実際にユーザー・プログラムを変換して使用する際に業務ロジックに問題が発生することがあります。
本節では、文字セットの固有の特性によって発生する可能性のあるソート順問題について説明し、その対処方法について説明します。
以下は、メインフレームで使用しているCOBOLソースをASCII文字に変換したソースの一部です。
IF W01-XX <= '99' THEN MOVE 'Y' TO W01-CC ELSE MOVE 'N' TO W01-CC END-IF.
EBCDICからASCIIへのソース変換は正常に行われましたが、ユーザー・プログラムに関してはビジネスロジックでエラーが発生する可能性があります。 |
以下は、EBCDIC文字とASCII文字のソート順です。
-
EBCDIC: a < z < A < Z < 0 < 9
-
ASCII: 0 < 9 < A < Z < a < z
上記の例では、W01-XXの値をAAと想定しています。プログラムがメインフレーム上で動作する場合はW01-CCにYが設定され、UNIX上で動作する場合はW01-CCにNが設定されます。
そのため、メインフレームの業務ロジックのまま変換するには、以下のようにソースを修正する必要があります。
IF W01-XX < 'zz' THEN MOVE 'Y' TO W01-CC ELSE MOVE 'N' TO W01-CC END-IF.
業務システム内の文字ソート順の処理時に発生する問題は簡単ではありませんが、ユーザー・プログラムを修正することで解決することができます。ただし、業務システム内の問題ではなく、一般のユーザーにも影響を与える可能性のある問題は、深刻な混乱を引き起こす可能性があります。
実際に業務システムを開発および運用するシステム・エンジニアは、EBCDICではZZ<99、ASCIIでは99<ZZであることを把握しており、文字セットの変換時にソート順を変更する必要があることを認識していますが、一般のユーザーがこれらの情報を常に把握しているのは容易ではありません。
以下は、業務画面を変換する例です。
[User Address List] -------------------------------------------------------------------------- ID : AAAAAAAA ID NAME ADDRESS ------------------------------------------------------------------------- AAAAAAAA KIM SEOUL BBBBBBBB LEE PUSAN CCCCCCCC PARK SEOUL HHHHHHHH AHN DAEGU LLLLLLLL CHO GWANGJU MMMMMMMM CHOI INCHEON NNNNNNNN KWAK BUPYOUNG XXXXXXXX IM SUNGNAM ZZZZZZZZ SEO GURI -------------------------------------------------------------------------- <F1> Menu <F2> Prev <F3> Next <Enter> Search
上記の業務ロジックは、メインフレーム環境では、IDの最小値であるAAAAAAAAを使用してすべてのID一覧を検索することができますが、オープン環境では、AAAAAAAAを入力しても、すべてのID一覧を検索することができません。
また、11111111というIDがあると想定した場合、メインフレーム環境では<F3>キーを押して次の画面を検索すると、11111111の結果が表示されますが、オープン環境では、ZZZZZZZZ以降のID一覧は表示されません。つまり、オープン環境についての知識がなく、既存のメインフレーム・ユーザーは、11111111というID情報が実際にプログラムに存在するとしても、それを認識することは難しいです。
以下は、オープン環境ですべてのID一覧を検索(AAAAAAAAの代わりに00000000を使用)する例です。
[User Address List] -------------------------------------------------------------------------- ID : 00000000 ID NAME ADDRESS ------------------------------------------------------------------------- 11111111 NOH SEOUL 88888888 KANG DAEJEON AAAAAAAA KIM SEOUL BBBBBBBB LEE PUSAN CCCCCCCC PARK SEOUL HHHHHHHH AHN DAEGU LLLLLLLL CHO GWANGJU MMMMMMMM CHOI INCHEON NNNNNNNN KWAK BUPYOUNG -------------------------------------------------------------------------- <F1> Menu <F2> Prev <F3> Next <Enter> Search
文字ソート順の問題も16進数値の処理問題と同様に、プログラムを直接確認してから判断しなければならないため、現在は専門のコンサルタントが問題の解決にあたっています。
3. 2バイト・スペースの処理
メインフレーム環境では、2バイト・スペースはX’4040’、つまり1バイト・スペースのX’40’を2つ合わせた値と同一値として認識されます。
10 W-K-00. 20 W-K-00-1 PIC X(01). 20 W-K-00-2 PIC X(01). 10 W-K-01 REDEFINES W-K-00. 20 W-K-01-1 PIC G(01). * . . . MOVE SPACE TO W-K-01-1. IF W-K-00-1 = SPACE THEN DISPLAY 'DOUBLE BYTE SPACE = SINGLE BYTE SPACE * 2' END-IF.
上記のCOBOLプログラムがメインフレーム環境で実行される場合は、「DOUBLE BYTE SPACE = SINGLE BYTE SPACE *2」というメッセージが出力されますが、オープン環境で実行される場合は、そのメッセージが出力されません。
そのため、メインフレームで2バイト・スペースを処理する方法は、オープン環境に移行されたときにユーザー・プログラムのロジックが変更される問題をもたらします。
このような問題が発生する理由は、韓国語の場合、オープン環境にデータを移行する際、EUC-KRで2バイト文字を変換しますが、EUC-KR文字セットでは、2バイト・スペースはX’8140’、1バイト・スペースはX’20’という値にマッピングされるため、「シングル・バイト・スペース + シングル・バイト・スペース = ダブル・バイト・スペース」という式が成立しないためです。
このような問題は、コンパイラーが提供する機能を使用して簡単に解決できる場合もありますが、そうでない場合もあります。
OpenFrameでは、オープン環境で2バイト・スペースを使用しないことを解決策として提示しています。なるべく、2バイト・スペースを使用しないようにし、2バイト・スペースを使用する必要がある場合は、2つの1バイト・スペースで2バイト・スペースを代替する方法を使用してください。COBOLコンパイラーは、2バイト・スペースを無視するオプションを提供しているため、このような問題は簡単に解決することができます。
OpenFrameのデータをメインフレーム環境に送信する場合は、2バイト・スペースを使用する必要があるため、2つの1バイト・スペースを使用して代替する方法は使用できません。このような場合は、OpenFrameのCPMで処理できるようにサポートしています。