Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -632,10 +632,16 @@ public static void setEnv(String envVarName, String envVarValue) {
*
* @param envVarName the name of an environment variable. The leading and trailing spaces are
* ignored.
* @param envVarValue the value of an environment variable to be set.
* @param envVarValue the value of an environment variable to be set. Trailing spaces and NUL
* bytes are stripped to match libcob's {@code cob_field_to_string} behavior.
*/
public static void setEnv(AbstractCobolField envVarName, AbstractCobolField envVarValue) {
CobolUtil.envVarTable.setProperty(envVarName.getString().trim(), envVarValue.getString());
// Name side uses String#trim() to drop both leading and trailing spaces, matching the
// behavior documented above. Value side uses fieldToString so only trailing spaces/NULs
// are stripped (leading spaces are meaningful in an environment value).
CobolUtil.envVarTable.setProperty(
envVarName.getString().trim(),
envVarValue.fieldToString(AbstractCobolField.charSetSJIS));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,25 @@ public String fieldToString() {
return new String(data.getByteArray(0, i + 1));
}

/**
* 末尾の空白とNULバイトを取り除いたうえで指定されたcharsetでデコードして文字列として返す.
* 本家CのopensourceCOBOLにおける{@code cob_field_to_string}と同等の処理を行う.
*
* @param charset デコードに使用するcharset
* @return 末尾の空白/NULを取り除いた文字列
*/
public String fieldToString(Charset charset) {
CobolDataStorage data = this.getDataStorage();
int end;
for (end = this.getSize(); end > 0; --end) {
byte b = data.getByte(end - 1);
if (b != ' ' && b != 0) {
break;
}
}
return new String(data.getByteArray(0, end), charset);
}

/**
* TODO: 準備中
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,21 @@ public static void displayEnvironment(AbstractCobolField f) {
* で設定された環境変数名に対して値を設定する. 環境変数名が未設定または空文字列の場合は{@link
* CobolExceptionId#COB_EC_IMP_DISPLAY}例外を設定する.
*
* <p>COBOL変数{@code f}の値は{@link AbstractCobolField#fieldToString(java.nio.charset.Charset)}
* によって末尾の空白とNULバイトが取り除かれてから環境変数値として設定される. これは本家CのopensourceCOBOLが
* {@code cob_display_env_value}内で{@code cob_field_to_string}を使用する挙動と一致する.
*
* @param f 設定する環境変数の値を保持するCOBOL変数
*/
public static void displayEnvValue(AbstractCobolField f) {
if (CobolUtil.cobLocalEnv == null || CobolUtil.cobLocalEnv.equals("")) {
CobolExceptionInfo.setException(CobolExceptionId.COB_EC_IMP_DISPLAY);
return;
}
CobolUtil.setEnv(CobolUtil.cobLocalEnv, f.getString());
// Strip trailing spaces and NULs so that PIC X(n) source fields do not
// leak padding into the environment variable value. Matches libcob's
// cob_field_to_string used by cob_display_env_value.
CobolUtil.setEnv(CobolUtil.cobLocalEnv, f.fieldToString(AbstractCobolField.charSetSJIS));
}

/**
Expand Down
71 changes: 71 additions & 0 deletions tests/jp-compat.src/special-names.at
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,77 @@ AT_CHECK([export TESTENV=envvalue && java prog], [0], [envvalue:newvalue])

AT_CLEANUP

AT_SETUP([DISPLAY ENVIRONMENT-VALUE strips trailing spaces])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT OUT-FILE ASSIGN OUTPATH
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD OUT-FILE.
01 OUT-REC PIC X(5).
WORKING-STORAGE SECTION.
01 WK-PATH PIC X(32).
PROCEDURE DIVISION.
MOVE SPACE TO WK-PATH.
STRING 'hello.txt' DELIMITED BY SIZE
INTO WK-PATH.
DISPLAY 'OUTPATH' UPON ENVIRONMENT-NAME.
DISPLAY WK-PATH UPON ENVIRONMENT-VALUE.
OPEN OUTPUT OUT-FILE.
MOVE 'HELLO' TO OUT-REC.
WRITE OUT-REC.
CLOSE OUT-FILE.
STOP RUN.
])

AT_CHECK([${COMPILE_JP_COMPAT} prog.cob], [0])
AT_CHECK([java prog], [0])
AT_CHECK([test -f hello.txt && cat hello.txt], [0], [HELLO
])

AT_CLEANUP

AT_SETUP([SET ENVIRONMENT strips trailing spaces])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT OUT-FILE ASSIGN OUTPATH2
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD OUT-FILE.
01 OUT-REC PIC X(5).
WORKING-STORAGE SECTION.
01 WK-PATH PIC X(32).
PROCEDURE DIVISION.
MOVE SPACE TO WK-PATH.
STRING 'world.txt' DELIMITED BY SIZE
INTO WK-PATH.
SET ENVIRONMENT 'OUTPATH2' TO WK-PATH.
OPEN OUTPUT OUT-FILE.
MOVE 'WORLD' TO OUT-REC.
WRITE OUT-REC.
CLOSE OUT-FILE.
STOP RUN.
])

AT_CHECK([${COMPILE_JP_COMPAT} prog.cob], [0])
AT_CHECK([java prog], [0])
AT_CHECK([test -f world.txt && cat world.txt], [0], [WORLD
])

AT_CLEANUP

AT_SETUP([SPECIAL NAMES unterminated])

AT_DATA([prog.cob], [
Expand Down