diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index b085369d..258f2083 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -8,18 +8,19 @@ jobs: run-tests: strategy: matrix: - os: ["ubuntu:22.04", "almalinux:9"] + #os: ["ubuntu:22.04", "almalinux:9"] + os: ["almalinux:9"] runs-on: ubuntu-latest container: image: ${{ matrix.os }} steps: - name: Install dependencies on Ubuntu 22.04 - if: matrix.os == 'ubuntu:22.04' + if: matrix.os == 'ubuntu:20.04' run: | - apt-get update -y - apt-get install -y default-jdk - apt-get install -y build-essential bison flex gettext texinfo automake autoconf libtool + apt update -y + apt install -y default-jdk + apt install -y build-essential bison flex gettext texinfo - name: Install dependencies on AlmaLinux 9 if: matrix.os == 'almalinux:9' @@ -38,61 +39,55 @@ jobs: ./configure --prefix=/usr/ make make install - export CLASSPATH=":/usr/lib/opensourcecobol4j/libcobj.jar:$HOME/.java_lib/sqlite.jar" - - #- name: Make test scripts - # run: | - # cd tests/ - # make - # cd ../ + export CLASSPATH=":/usr/lib/opensourcecobol4j/libcobj.jar:$HOME/.java_lib/sqlite.jar" - #- name: Run tests "command-line-options" - # run: | - # export CLASSPATH=":/usr/lib/opensourcecobol4j/libcobj.jar:$HOME/.java_lib/sqlite.jar" - # cd tests/ - # ./command-line-options - # cd ../ + - name: Run tests "command-line-options" + run: | + export CLASSPATH=":/usr/lib/opensourcecobol4j/libcobj.jar:$HOME/.java_lib/sqlite.jar" + cd tests/ + ./command-line-options + cd ../ - #- name: Run tests "misc" - # run: | - # export CLASSPATH=":/usr/lib/opensourcecobol4j/libcobj.jar:$HOME/.java_lib/sqlite.jar" - # cd tests/ - # ./misc - # cd ../ + - name: Run tests "misc" + run: | + export CLASSPATH=":/usr/lib/opensourcecobol4j/libcobj.jar:$HOME/.java_lib/sqlite.jar" + cd tests/ + ./misc + cd ../ - #- name: Run tests "data-rep" - # run: | - # export CLASSPATH=":/usr/lib/opensourcecobol4j/libcobj.jar:$HOME/.java_lib/sqlite.jar" - # cd tests/ - # ./data-rep - # cd ../ + - name: Run tests "data-rep" + run: | + export CLASSPATH=":/usr/lib/opensourcecobol4j/libcobj.jar:$HOME/.java_lib/sqlite.jar" + cd tests/ + ./data-rep + cd ../ - #- name: Run tests "i18n_sjis" - # run: | - # export CLASSPATH=":/usr/lib/opensourcecobol4j/libcobj.jar:$HOME/.java_lib/sqlite.jar" - # cd tests/ - # ./i18n_sjis + - name: Run tests "i18n_sjis" + run: | + export CLASSPATH=":/usr/lib/opensourcecobol4j/libcobj.jar:$HOME/.java_lib/sqlite.jar" + cd tests/ + ./i18n_sjis - #- name: Run tests "jp-compat" - # run: | - # export CLASSPATH=":/usr/lib/opensourcecobol4j/libcobj.jar:$HOME/.java_lib/sqlite.jar" - # cd tests/ - # ./jp-compat - # cd ../ + - name: Run tests "jp-compat" + run: | + export CLASSPATH=":/usr/lib/opensourcecobol4j/libcobj.jar:$HOME/.java_lib/sqlite.jar" + cd tests/ + ./jp-compat + cd ../ - #- name: Run tests "run" - # run: | - # export CLASSPATH=":/usr/lib/opensourcecobol4j/libcobj.jar:$HOME/.java_lib/sqlite.jar" - # cd tests/ - # ./run - # cd ../ + - name: Run tests "run" + run: | + export CLASSPATH=":/usr/lib/opensourcecobol4j/libcobj.jar:$HOME/.java_lib/sqlite.jar" + cd tests/ + ./run + cd ../ - #- name: Run tests "syntax" - # run: | - # export CLASSPATH=":/usr/lib/opensourcecobol4j/libcobj.jar:$HOME/.java_lib/sqlite.jar" - # cd tests/ - # ./syntax - # cd ../ + - name: Run tests "syntax" + run: | + export CLASSPATH=":/usr/lib/opensourcecobol4j/libcobj.jar:$HOME/.java_lib/sqlite.jar" + cd tests/ + ./syntax + cd ../ - name: Run NIST test run: | @@ -116,10 +111,11 @@ jobs: # Checkout opensource COBOL - name: Checkout opensource COBOL 4j uses: actions/checkout@v2 - - - name: Install dependencies - run: | - sudo apt-get install default-jdk + + - uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: '17' # Download google-java-format and PMD - name: Install dependencies diff --git a/cobj/codegen.c b/cobj/codegen.c index 8a42cb4a..494c0e83 100644 --- a/cobj/codegen.c +++ b/cobj/codegen.c @@ -4150,6 +4150,113 @@ joutput_initial_values (struct cb_field *p) } } +struct call_parameter_list { + struct call_paramter_list* next; + struct cb_field* field; + cb_tree x; +}; +struct call_parameter_list* call_parameter_cache = NULL; + +static void +joutput_java_entrypoint (struct cb_program *prog, cb_tree parameter_list) +{ + cb_tree l; + struct cb_field *f; + char arg_field_name[COB_SMALL_BUFF]; + + joutput_prefix(); + joutput ("CobolResultSet execute ("); + + int k; + for (l = parameter_list; l; l = CB_CHAIN (l)) { + struct cb_field* arg_field = cb_field (CB_VALUE (l)); + int type = cb_tree_type(CB_TREE(arg_field)); + char* field_name = get_java_identifier_field(arg_field); + get_java_identifier_helper(arg_field, arg_field_name); + if(type & COB_TYPE_NUMERIC) { + if(arg_field->pic->scale > 0) { + joutput("double"); + } else { + joutput("int"); + } + } else { + joutput("String"); + } + joutput(" %s", arg_field_name); + if(CB_CHAIN(l)) { + joutput(", "); + } + + struct call_parameter_list* call_parameter = malloc(sizeof(struct call_parameter_list)); + call_parameter->next = call_parameter_cache; + call_parameter->field = arg_field; + call_parameter->x = CB_VALUE (l); + call_parameter_cache = call_parameter; + } + + joutput(") {\n"); + joutput_indent_level += 2; + + for (l = parameter_list; l; l = CB_CHAIN (l)) { + struct cb_field* arg_field = cb_field (CB_VALUE (l)); + char* field_name = get_java_identifier_field(arg_field); + char* base_name = get_java_identifier_base(arg_field); + get_java_identifier_helper(arg_field, arg_field_name); + joutput_line("this.%s.setDataStorage(new CobolDataStorage(%d));", + field_name, + arg_field->size + ); + joutput_line("this.%s.moveFrom(%s);", + field_name, + arg_field_name); + joutput_line("this.%s = this.%s.getDataStorage();", base_name, field_name); + free(field_name); + free(base_name); + } + + joutput_line("int returnCode = run_module(0);", prog->program_id); + + joutput_prefix(); + joutput("return new CobolResultSet(returnCode"); + if(parameter_list) { + joutput(",\n"); + joutput_indent_level += 2; + for (l = parameter_list; l; l = CB_CHAIN (l)) { + struct cb_field* arg_field = cb_field (CB_VALUE (l)); + char* field_name = get_java_identifier_field(arg_field); + int type = cb_tree_type(CB_TREE(arg_field)); + joutput_prefix(); + const char* constructor; + const char* getter; + if(type & COB_TYPE_NUMERIC) { + if(arg_field->pic->scale > 0) { + constructor = "CobolResultDouble"; + getter = "getDouble"; + } else { + constructor = "CobolResultInt"; + getter = "getInt"; + } + } else { + constructor = "CobolResultString"; + getter = "getString"; + } + joutput("new %s(%s.%s())", + constructor, + field_name, + getter + ); + joutput(CB_CHAIN(l) ? ",\n" : "\n"); + free(field_name); + } + joutput_indent_level -= 2; + joutput_prefix(); + } + + joutput(");\n"); + joutput_indent_level -= 2; + joutput_line("}\n"); +} + static void joutput_internal_function (struct cb_program *prog, cb_tree parameter_list) { @@ -4193,9 +4300,13 @@ joutput_internal_function (struct cb_program *prog, cb_tree parameter_list) parmnum++; } } - + joutput_line("return this.run_module(entry);"); + joutput_indent_level -=2; + joutput_line("}"); joutput("\n"); + joutput_line ("int run_module (int entry) {"); + joutput_indent_level += 2; //if (!prog->flag_chained) { // for (l = parameter_list; l; l = CB_CHAIN (l)) { // joutput_line ("if (fields.length > %d) {", parmnum); @@ -4939,23 +5050,54 @@ void joutput_init_method(struct cb_program *prog) { joutput_prefix(); char* field_name = get_java_identifier_field(k->f); - joutput ("%s\t= ", field_name); - free(field_name); + if (!k->f->flag_local && !k->f->flag_item_external) { + joutput ("%s\t= ", field_name); joutput_field (k->x); } else { + joutput ("%s\t= ", field_name); joutput ("CobolFieldFactory.makeCobolField("); joutput_size (k->x); - joutput (", (CobolDataStorage)null, "); + joutput(", (CobolDataStorage)null, "); joutput_attr (k->x); joutput (")"); } + + free(field_name); joutput (";\t/* %s */\n", k->f->name); } joutput("\n"); joutput_line ("/* End of fields */\n\n"); } + if(call_parameter_cache) { + joutput_line("/* Call parameters */"); + struct call_parameter_list* l; + for(l = call_parameter_cache; l; l=l->next) { + int cached = 0; + char* call_parameter_field_name = get_java_identifier_field(l->field); + if(field_cache) { + struct field_list* f; + for(f = field_cache; f; f=f->next) { + char* field_name = get_java_identifier_field(f->f); + if(f->f == l->field && strcmp(call_parameter_field_name, field_name) == 0) { + cached = 1; + free(field_name); + break; + } + free(field_name); + } + } + if(!cached) { + joutput_prefix(); + joutput("%s = CobolFieldFactory.makeCobolField(", call_parameter_field_name); + joutput("%d, (CobolDataStorage)null, ", l->field->size); + joutput_attr (l->x); + joutput (");\n"); + } + free(call_parameter_field_name); + } + } /* AbstractCobolField型変数の初期化(定数) */ if (literal_cache) { @@ -5308,13 +5450,6 @@ void joutput_declare_member_variables(struct cb_program *prog, cb_tree parameter joutput_line ("/* End of data storage */\n\n"); } - joutput_line("/* Call parameters */"); - for (l = parameter_list; l; l = CB_CHAIN (l)) { - char* base_name = get_java_identifier_base(cb_field (CB_VALUE (l))); - joutput_line("private CobolDataStorage %s;", base_name); - free(base_name); - } - /* Dangling linkage section items */ int seen = 0; for (f = prog->linkage_storage; f; f = f->sister) { @@ -5408,6 +5543,32 @@ void joutput_declare_member_variables(struct cb_program *prog, cb_tree parameter joutput_line ("private CobolFieldAttribute %s%d;", CB_PREFIX_ATTR, j->id); } + joutput("\n"); + } + + if(call_parameter_cache) { + joutput_line("/* Call parameters */"); + struct call_parameter_list* l; + for(l = call_parameter_cache; l; l=l->next) { + int cached = 0; + if(field_cache) { + struct field_list* f; + for(f = field_cache; f; f=f->next) { + if(f->f == l->field) { + cached = 1; + break; + } + } + } + if(!cached) { + char* field_name = get_java_identifier_field(l->field); + joutput_line("private AbstractCobolField %s;", field_name); + free(field_name); + } + char* base_name = get_java_identifier_base(l->field); + joutput_line("private CobolDataStorage %s;", base_name); + free(base_name); + } } joutput("\n"); @@ -5770,6 +5931,7 @@ codegen (struct cb_program *prog, const int nested, char** program_id_list) joutput_line("import jp.osscons.opensourcecobol.libcobj.termio.*;"); joutput_line("import jp.osscons.opensourcecobol.libcobj.call.*;"); joutput_line("import jp.osscons.opensourcecobol.libcobj.file.*;"); + joutput_line("import jp.osscons.opensourcecobol.libcobj.ui.*;"); joutput_line("import java.util.Optional;"); joutput("\n"); @@ -5830,6 +5992,7 @@ codegen (struct cb_program *prog, const int nested, char** program_id_list) //} create_label_id_map(prog); + joutput_java_entrypoint(prog, prog->parameter_list); joutput_internal_function (prog, prog->parameter_list); joutput_execution_list(prog); diff --git a/libcobj/Makefile.am b/libcobj/Makefile.am index e632f41f..47f0f83f 100644 --- a/libcobj/Makefile.am +++ b/libcobj/Makefile.am @@ -61,7 +61,13 @@ SRC_FILES = \ ./src/jp/osscons/opensourcecobol/libcobj/file/CobolSequentialFile.java \ ./src/jp/osscons/opensourcecobol/libcobj/file/FileStruct.java \ ./src/jp/osscons/opensourcecobol/libcobj/file/KeyComponent.java \ - ./src/jp/osscons/opensourcecobol/libcobj/termio/CobolTerminal.java + ./src/jp/osscons/opensourcecobol/libcobj/termio/CobolTerminal.java \ + ./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultSetException.java \ + ./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultSet.java \ + ./src/jp/osscons/opensourcecobol/libcobj/ui/CobolCallResult.java \ + ./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultInt.java \ + ./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultString.java \ + ./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultDouble.java all: libcobj.jar diff --git a/libcobj/Makefile.in b/libcobj/Makefile.in index 87c53dd4..d2035574 100644 --- a/libcobj/Makefile.in +++ b/libcobj/Makefile.in @@ -339,7 +339,13 @@ SRC_FILES = \ ./src/jp/osscons/opensourcecobol/libcobj/file/CobolSequentialFile.java \ ./src/jp/osscons/opensourcecobol/libcobj/file/FileStruct.java \ ./src/jp/osscons/opensourcecobol/libcobj/file/KeyComponent.java \ - ./src/jp/osscons/opensourcecobol/libcobj/termio/CobolTerminal.java + ./src/jp/osscons/opensourcecobol/libcobj/termio/CobolTerminal.java \ + ./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultSetException.java \ + ./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultSet.java \ + ./src/jp/osscons/opensourcecobol/libcobj/ui/CobolCallResult.java \ + ./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultInt.java \ + ./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultString.java \ + ./src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultDouble.java all: all-am diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/AbstractCobolField.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/AbstractCobolField.java index 5405eafd..2b26b0d5 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/AbstractCobolField.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/AbstractCobolField.java @@ -20,6 +20,7 @@ import java.math.BigDecimal; import java.nio.ByteBuffer; +import java.nio.charset.Charset; import jp.osscons.opensourcecobol.libcobj.common.CobolConstant; import jp.osscons.opensourcecobol.libcobj.common.CobolModule; import jp.osscons.opensourcecobol.libcobj.common.CobolUtil; @@ -163,7 +164,13 @@ public int getInt() { /** * @return */ - public abstract double getDouble(); + public double getDouble() { + try { + return Double.parseDouble(this.getString()); + } catch (Exception e) { + return 0; + } + } /** * 数値を表すデータが実装すべきメソッド. 保持する数値データをCobolDecimal型に変換する. @@ -585,19 +592,87 @@ protected void moveFromAll(AbstractCobolField src) { * * @param field 代入元のデータ(String型) */ - public abstract void moveFrom(String string); + public void moveFrom(String s) { + // The maximum number of digits of int type in decimal is 10 + + byte[] bytes = s.getBytes(Charset.forName("SJIS")); + + CobolDataStorage storage = new CobolDataStorage(bytes.length); + storage.memcpy(bytes); + + CobolFieldAttribute attr = + new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_ALPHANUMERIC, + bytes.length, + 0, + 0, + String.format("X(%d)", bytes.length)); + + AbstractCobolField tmp = CobolFieldFactory.makeCobolField(bytes.length, storage, attr); + this.moveFrom(tmp); + } /** * 引数で与えらえられたデータからthisへの代入を行う * * @param field 代入元のデータ(int型) */ - public abstract void moveFrom(int number); + public void moveFrom(int number) { + // The maximum number of digits of int type in decimal is 10 + final int length = 10; + + CobolDataStorage storage = new CobolDataStorage(length); + String formatted_number_string = String.format("%10d", Math.abs(number)); + storage.memcpy(formatted_number_string, length); + if (number < 0) { + storage.setByte(length - 1, (byte) (storage.getByte(length - 1) + 0x40)); + } + + CobolFieldAttribute attr = + new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_DISPLAY, + length, + 0, + CobolFieldAttribute.COB_FLAG_HAVE_SIGN, + "S9(10)"); + + AbstractCobolField tmp = CobolFieldFactory.makeCobolField(length, storage, attr); + this.moveFrom(tmp); + } /** * 引数で与えらえられたデータからthisへの代入を行う * * @param field 代入元のデータ(double型) */ - public abstract void moveFrom(double number); + public void moveFrom(double number) { + String s = Double.toString(Math.abs(number)); + String ss; + int scale; + ss = s.replace("+", "").replace("-", ""); + int pointIndex = ss.indexOf('.'); + if (pointIndex < 0) { + scale = 0; + } else { + scale = ss.length() - 1 - pointIndex; + ss = ss.replace(".", ""); + } + + CobolDataStorage storage = new CobolDataStorage(ss.length()); + storage.memcpy(ss, ss.length()); + + CobolFieldAttribute attr = + new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_DISPLAY, + ss.length(), + scale, + CobolFieldAttribute.COB_FLAG_HAVE_SIGN, + ""); + + AbstractCobolField tmp = CobolFieldFactory.makeCobolField(ss.length(), storage, attr); + if (number < 0) { + tmp.putSign(-1); + } + this.moveFrom(tmp); + } /** * 引数で与えらえられたデータからthisへの代入を行う * diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolAlphanumericEditedField.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolAlphanumericEditedField.java index f303b878..1ef5a377 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolAlphanumericEditedField.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolAlphanumericEditedField.java @@ -47,12 +47,6 @@ public String getString() { return null; } - @Override - public double getDouble() { - // TODO Auto-generated method stub - return 0; - } - @Override public CobolDecimal getDecimal() { // TODO Auto-generated method stub diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolAlphanumericField.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolAlphanumericField.java index 299fdb63..4a84669c 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolAlphanumericField.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolAlphanumericField.java @@ -64,11 +64,6 @@ public int getInt() { throw new CobolRuntimeException(CobolRuntimeException.COBOL_FITAL_ERROR, "未対応"); } - @Override - public double getDouble() { - throw new CobolRuntimeException(CobolRuntimeException.COBOL_FITAL_ERROR, "未対応"); - } - @Override public void setDecimal(BigDecimal decimal) { // TODO 自動生成されたメソッド・スタブ diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolGroupField.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolGroupField.java index 78140f00..faa0bbee 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolGroupField.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolGroupField.java @@ -63,12 +63,6 @@ public int getInt() { return 0; } - /** TODO */ - @Override - public double getDouble() { - return 0; - } - /** TODO */ @Override public CobolDecimal getDecimal() { diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNationalEditedField.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNationalEditedField.java index df80494b..3890d927 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNationalEditedField.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNationalEditedField.java @@ -46,11 +46,6 @@ public String getString() { return null; } - @Override - public double getDouble() { - return 0; - } - @Override public CobolDecimal getDecimal() { return null; diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNationalField.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNationalField.java index 4e975390..bde0d27b 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNationalField.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNationalField.java @@ -64,11 +64,6 @@ public int getInt() { return 0; } - @Override - public double getDouble() { - return 0; - } - @Override public CobolDecimal getDecimal() { return null; diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericBinaryField.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericBinaryField.java index f48f1996..35e5401a 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericBinaryField.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericBinaryField.java @@ -125,12 +125,6 @@ public int getSign() { } } - /** TODO */ - @Override - public double getDouble() { - return 0; - } - /** TODO */ @Override public void setDecimal(BigDecimal decimal) {} diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericEditedField.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericEditedField.java index cc6a3499..efd849fe 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericEditedField.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericEditedField.java @@ -46,11 +46,6 @@ public String getString() { return null; } - @Override - public double getDouble() { - return 0; - } - @Override public CobolDecimal getDecimal() { return null; diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericField.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericField.java index 968a9d4c..b2b2a44e 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericField.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericField.java @@ -146,12 +146,6 @@ public int getInt() { return val; } - /** TODO */ - @Override - public double getDouble() { - throw new CobolRuntimeException(CobolRuntimeException.COBOL_FITAL_ERROR, "未対応"); - } - @Override public void setDecimal(BigDecimal decimal) { byte[] decimalBytes = decimal.toPlainString().getBytes(); @@ -810,13 +804,18 @@ public void moveFrom(String string) { */ @Override public void moveFrom(int number) { + int n = Math.abs(number); for (int i = 0; i < this.size; ++i) { this.dataStorage.setByte(i, (byte) 0x30); } for (int i = this.size - 1; i >= 0; --i) { - this.dataStorage.setByte(i, (byte) (0x30 + number % 10)); - number /= 10; + this.dataStorage.setByte(i, (byte) (0x30 + n % 10)); + n /= 10; + } + + if (number < 0 && this.getAttribute().isFlagHaveSign()) { + this.putSign(-1); } } @@ -1027,10 +1026,10 @@ public CobolNumericField getNumericField() { * * @param field 代入元のデータ(double型) */ - @Override + /*@Override public void moveFrom(double number) { this.moveFrom((int) number); - } + }*/ /** * 引数で与えらえられたデータからthisへの代入を行う diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericPackedField.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericPackedField.java index eeede058..54f327d1 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericPackedField.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericPackedField.java @@ -186,12 +186,6 @@ public String getString() { } } - /** TODO */ - @Override - public double getDouble() { - throw new CobolRuntimeException(CobolRuntimeException.COBOL_FITAL_ERROR, "未対応"); - } - @Override public void setDecimal(BigDecimal decimal) { byte[] decimalBytes = decimal.toPlainString().getBytes(); @@ -460,16 +454,6 @@ public CobolNumericField getNumericField() { return field; } - /** - * 引数で与えらえられたデータからthisへの代入を行う - * - * @param field 代入元のデータ(double型) - */ - @Override - public void moveFrom(double number) { - this.moveFrom((int) number); - } - /** * 引数で与えらえられたデータからthisへの代入を行う * diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/ui/CobolCallResult.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/ui/CobolCallResult.java new file mode 100644 index 00000000..39105dbc --- /dev/null +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/ui/CobolCallResult.java @@ -0,0 +1,15 @@ +package jp.osscons.opensourcecobol.libcobj.ui; + +public class CobolCallResult { + public int getInt() throws CobolResultSetException { + throw new CobolResultSetException("The result type is not 'int'"); + } + + public double getDouble() throws CobolResultSetException { + throw new CobolResultSetException("The result type is not 'double'"); + } + + public String getString() throws CobolResultSetException { + throw new CobolResultSetException("The result type is not 'String'"); + } +} diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultDouble.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultDouble.java new file mode 100644 index 00000000..1b4bbefc --- /dev/null +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultDouble.java @@ -0,0 +1,13 @@ +package jp.osscons.opensourcecobol.libcobj.ui; + +public class CobolResultDouble extends CobolCallResult { + private double value; + + public CobolResultDouble(double d) { + this.value = d; + } + + public double getDouble() throws CobolResultSetException { + return this.value; + } +} diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultInt.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultInt.java new file mode 100644 index 00000000..3cbc2499 --- /dev/null +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultInt.java @@ -0,0 +1,13 @@ +package jp.osscons.opensourcecobol.libcobj.ui; + +public class CobolResultInt extends CobolCallResult { + private int value; + + public CobolResultInt(int i) { + this.value = i; + } + + public int getInt() throws CobolResultSetException { + return this.value; + } +} diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultSet.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultSet.java new file mode 100644 index 00000000..4dda4a9a --- /dev/null +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultSet.java @@ -0,0 +1,36 @@ +package jp.osscons.opensourcecobol.libcobj.ui; + +public class CobolResultSet { + private CobolCallResult results[]; + private int returnCode; + + public CobolResultSet(int returnCode, CobolCallResult... results) { + this.returnCode = returnCode; + this.results = results; + } + + private void checkIndexInValidRange(int index) throws CobolResultSetException { + if (results.length == 0 || index < 1 || this.results.length < index) { + throw new CobolResultSetException("The index is out of range."); + } + } + + public int getReturnCode() { + return this.returnCode; + } + + public String getString(int index) throws CobolResultSetException { + this.checkIndexInValidRange(index); + return this.results[index - 1].getString(); + } + + public int getInt(int index) throws CobolResultSetException { + this.checkIndexInValidRange(index); + return this.results[index - 1].getInt(); + } + + public double getDouble(int index) throws CobolResultSetException { + this.checkIndexInValidRange(index); + return this.results[index - 1].getDouble(); + } +} diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultSetException.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultSetException.java new file mode 100644 index 00000000..e8a72613 --- /dev/null +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultSetException.java @@ -0,0 +1,7 @@ +package jp.osscons.opensourcecobol.libcobj.ui; + +public class CobolResultSetException extends Exception { + public CobolResultSetException(String message) { + super(message); + } +} diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultString.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultString.java new file mode 100644 index 00000000..28200631 --- /dev/null +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/ui/CobolResultString.java @@ -0,0 +1,13 @@ +package jp.osscons.opensourcecobol.libcobj.ui; + +public class CobolResultString extends CobolCallResult { + private String value; + + public CobolResultString(String s) { + this.value = s; + } + + public String getString() throws CobolResultSetException { + return this.value; + } +} diff --git a/tests/Makefile.am b/tests/Makefile.am index 38dfe88a..00df3fce 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -160,7 +160,8 @@ misc_DEPENDENCIES = \ misc.src/current-date.at \ misc.src/comp3-is-numeric.at \ misc.src/high-low-value.at \ - misc.src/move-sign-leading-separate-to-signed-comp3.at + misc.src/move-sign-leading-separate-to-signed-comp3.at \ + misc.src/java-interface.at EXTRA_DIST = $(srcdir)/package.m4 \ $(TESTS) \ diff --git a/tests/Makefile.in b/tests/Makefile.in index eac835f7..ffd02b1a 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -699,7 +699,8 @@ misc_DEPENDENCIES = \ misc.src/current-date.at \ misc.src/comp3-is-numeric.at \ misc.src/high-low-value.at \ - misc.src/move-sign-leading-separate-to-signed-comp3.at + misc.src/move-sign-leading-separate-to-signed-comp3.at \ + misc.src/java-interface.at EXTRA_DIST = $(srcdir)/package.m4 \ $(TESTS) \ diff --git a/tests/misc.at b/tests/misc.at index bebc36f9..078c4ccb 100644 --- a/tests/misc.at +++ b/tests/misc.at @@ -23,3 +23,4 @@ m4_include([current-date.at]) m4_include([comp3-is-numeric.at]) m4_include([high-low-value.at]) m4_include([move-sign-leading-separate-to-signed-comp3.at]) +m4_include([java-interface.at]) diff --git a/tests/misc.src/java-interface.at b/tests/misc.src/java-interface.at new file mode 100644 index 00000000..904a07a9 --- /dev/null +++ b/tests/misc.src/java-interface.at @@ -0,0 +1,475 @@ +AT_SETUP([no-argument]) + +AT_DATA([b.cbl], [ + identification division. + program-id. b. + data division. + linkage section. + procedure division. + display " b". +]) + +AT_DATA([a.java], [ +import jp.osscons.opensourcecobol.libcobj.ui.*; +public class a { + public static void main(String@<:@@:>@ args) { + b prog = new b(); + CobolResultSet rs = prog.execute(); + } +} +]) + +AT_CHECK([cobj b.cbl]) +AT_CHECK([javac a.java]) +AT_CHECK([java a], [0], +[ b +]) + +AT_CLEANUP + +AT_SETUP([PIC 9(3)]) + +AT_DATA([b.cbl], [ + identification division. + program-id. b. + data division. + linkage section. + 01 arg pic 9(3). + procedure division using arg. + display " arg: " arg. + add 1 to arg. +]) + +AT_DATA([a.java], [ +import jp.osscons.opensourcecobol.libcobj.ui.*; +public class a { + public static void main(String@<:@@:>@ args) { + b prog = new b(); + CobolResultSet rs; + int@<:@@:>@ data_list = {0, 1, 2, 998}; + try{ + for(int data : data_list) { + rs = prog.execute(data); + System.out.println(" arg: " + rs.getInt(1)); + } + } catch(CobolResultSetException e) { + e.printStackTrace(); + } + } +} +]) + +AT_CHECK([cobj b.cbl]) +AT_CHECK([javac a.java]) +AT_CHECK([java a], [0], +[ arg: 000 + arg: 1 + arg: 001 + arg: 2 + arg: 002 + arg: 3 + arg: 998 + arg: 999 +]) + +AT_CLEANUP + +AT_SETUP([PIC S9(3)]) + +AT_DATA([b.cbl], [ + identification division. + program-id. b. + data division. + linkage section. + 01 arg pic S9(3). + procedure division using arg. + display " arg: " arg. + add 1 to arg. +]) + +AT_DATA([a.java], [ +import jp.osscons.opensourcecobol.libcobj.ui.*; +public class a { + public static void main(String@<:@@:>@ args) { + b prog = new b(); + CobolResultSet rs; + int@<:@@:>@ data_list = {-999, -2, -1, 0, 1, 2, 998}; + try{ + for(int data : data_list) { + rs = prog.execute(data); + System.out.println(" arg: " + rs.getInt(1)); + } + } catch(CobolResultSetException e) { + e.printStackTrace(); + } + } +} +]) + +AT_CHECK([cobj b.cbl]) +AT_CHECK([javac a.java]) +AT_CHECK([java a], [0], +[ arg: -999 + arg: -998 + arg: -002 + arg: -1 + arg: -001 + arg: 0 + arg: +000 + arg: 1 + arg: +001 + arg: 2 + arg: +002 + arg: 3 + arg: +998 + arg: 999 +]) + +AT_CLEANUP + +AT_SETUP([PIC S9(3)V99]) + +AT_DATA([b.cbl], [ + identification division. + program-id. b. + data division. + linkage section. + 01 arg pic S9(3)V99. + procedure division using arg. + display " arg: " arg. + add 1 to arg. +]) + +AT_DATA([a.java], [ +import jp.osscons.opensourcecobol.libcobj.ui.*; +public class a { + public static void main(String@<:@@:>@ args) { + b prog = new b(); + CobolResultSet rs; + double@<:@@:>@ data_list = {-999.99, -2.01, -1.01, -1.00, 0, 1.01, 2.01, 998.99}; + try{ + for(double data : data_list) { + rs = prog.execute(data); + System.out.println(" arg: " + rs.getDouble(1)); + } + } catch(CobolResultSetException e) { + e.printStackTrace(); + } + } +} +]) + +AT_CHECK([cobj b.cbl]) +AT_CHECK([javac a.java]) +AT_CHECK([java a], [0], +[ arg: -999.99 + arg: -998.99 + arg: -002.01 + arg: -1.01 + arg: -001.01 + arg: -0.01 + arg: -001.00 + arg: 0.0 + arg: +000.00 + arg: 1.0 + arg: +001.01 + arg: 2.01 + arg: +002.01 + arg: 3.01 + arg: +998.99 + arg: 999.99 +]) + +AT_CLEANUP + + +AT_SETUP([PIC 9(3) USAGE COMP-3]) + +AT_DATA([b.cbl], [ + identification division. + program-id. b. + data division. + linkage section. + 01 arg pic 9(3) USAGE COMP-3. + procedure division using arg. + display " arg: " arg. + add 1 to arg. +]) + +AT_DATA([a.java], [ +import jp.osscons.opensourcecobol.libcobj.ui.*; +public class a { + public static void main(String@<:@@:>@ args) { + b prog = new b(); + CobolResultSet rs; + int@<:@@:>@ data_list = {0, 1, 2, 998}; + try{ + for(int data : data_list) { + rs = prog.execute(data); + System.out.println(" arg: " + rs.getInt(1)); + } + } catch(CobolResultSetException e) { + e.printStackTrace(); + } + } +} +]) + +AT_CHECK([cobj b.cbl]) +AT_CHECK([javac a.java]) +AT_CHECK([java a], [0], +[ arg: 000 + arg: 1 + arg: 001 + arg: 2 + arg: 002 + arg: 3 + arg: 998 + arg: 999 +]) + +AT_CLEANUP + +AT_SETUP([PIC S9(3) USAGE COMP-3]) + +AT_DATA([b.cbl], [ + identification division. + program-id. b. + data division. + linkage section. + 01 arg pic S9(3) USAGE COMP-3. + procedure division using arg. + display " arg: " arg. + add 1 to arg. +]) + +AT_DATA([a.java], [ +import jp.osscons.opensourcecobol.libcobj.ui.*; +public class a { + public static void main(String@<:@@:>@ args) { + b prog = new b(); + CobolResultSet rs; + int@<:@@:>@ data_list = {-999, -2, -1, 0, 1, 2, 998}; + try{ + for(int data : data_list) { + rs = prog.execute(data); + System.out.println(" arg: " + rs.getInt(1)); + } + } catch(CobolResultSetException e) { + e.printStackTrace(); + } + } +} +]) + +AT_CHECK([cobj b.cbl]) +AT_CHECK([javac a.java]) +AT_CHECK([java a], [0], +[ arg: -999 + arg: -998 + arg: -002 + arg: -1 + arg: -001 + arg: 0 + arg: +000 + arg: 1 + arg: +001 + arg: 2 + arg: +002 + arg: 3 + arg: +998 + arg: 999 +]) + +AT_CLEANUP + +AT_SETUP([PIC S9(3)V99 USAGE COMP-3]) + +AT_DATA([b.cbl], [ + identification division. + program-id. b. + data division. + linkage section. + 01 arg pic S9(3)V99 USAGE COMP-3. + procedure division using arg. + display " arg: " arg. + add 1 to arg. +]) + +AT_DATA([a.java], [ +import jp.osscons.opensourcecobol.libcobj.ui.*; +public class a { + public static void main(String@<:@@:>@ args) { + b prog = new b(); + CobolResultSet rs; + double@<:@@:>@ data_list = {-999.99, -2.01, -1.01, -1.00, 0, 1.01, 2.01, 998.99}; + try{ + for(double data : data_list) { + rs = prog.execute(data); + System.out.println(" arg: " + rs.getDouble(1)); + } + } catch(CobolResultSetException e) { + e.printStackTrace(); + } + } +} +]) + +AT_CHECK([cobj b.cbl]) +AT_CHECK([javac a.java]) +AT_CHECK([java a], [0], +[ arg: -999.99 + arg: -998.99 + arg: -002.01 + arg: -1.01 + arg: -001.01 + arg: -0.01 + arg: -001.00 + arg: 0.0 + arg: +000.00 + arg: 1.0 + arg: +001.01 + arg: 2.01 + arg: +002.01 + arg: 3.01 + arg: +998.99 + arg: 999.99 +]) + +AT_CLEANUP + +AT_SETUP([PIC X(3)]) + +AT_DATA([b.cbl], [ + identification division. + program-id. b. + data division. + linkage section. + 01 arg pic X(3). + procedure division using arg. + display " arg: " arg. + MOVE "123" TO arg. +]) + +AT_DATA([a.java], [ +import jp.osscons.opensourcecobol.libcobj.ui.*; +public class a { + public static void main(String@<:@@:>@ args) { + b prog = new b(); + CobolResultSet rs; + try{ + rs = prog.execute("abc"); + System.out.println(" arg: " + rs.getString(1)); + } catch(CobolResultSetException e) { + e.printStackTrace(); + } + } +} +]) + +AT_CHECK([cobj b.cbl]) +AT_CHECK([javac a.java]) +AT_CHECK([java a], [0], +[ arg: abc + arg: 123 +]) + +AT_CLEANUP + +AT_SETUP([Out of range]) + +AT_DATA([b.cbl], [ + identification division. + program-id. b. + data division. + linkage section. + 01 arg pic 9(3). + procedure division using arg. + add 1 to arg. +]) + +AT_DATA([a.java], [ +import jp.osscons.opensourcecobol.libcobj.ui.*; +public class a { + public static void main(String@<:@@:>@ args) { + b prog = new b(); + CobolResultSet rs; + try{ + rs = prog.execute(0); + System.out.println(" arg: " + rs.getInt(2)); + } catch(CobolResultSetException e) { + e.printStackTrace(); + } + } +} +]) + +AT_CHECK([cobj b.cbl]) +AT_CHECK([javac a.java]) +AT_CHECK([java a 2>&1 | grep 'The index is out of range' > /dev/null], [0]) +AT_CLEANUP + +AT_SETUP([Type mismatch]) + +AT_DATA([b.cbl], [ + identification division. + program-id. b. + data division. + linkage section. + 01 arg-i pic 9(3). + 01 arg-d pic 9(3)V9. + 01 arg-s pic X(3). + procedure division using arg-i arg-d arg-s. +]) + +AT_DATA([a.java], [ +import jp.osscons.opensourcecobol.libcobj.ui.*; +public class a { + public static void main(String@<:@@:>@ args) { + b prog = new b(); + CobolResultSet rs = prog.execute(1, 1.1, "abc"); + try{ + rs.getDouble(1); + } catch(CobolResultSetException e) { + e.printStackTrace(); + } + try{ + rs.getString(1); + } catch(CobolResultSetException e) { + e.printStackTrace(); + } + try{ + rs.getInt(2); + } catch(CobolResultSetException e) { + e.printStackTrace(); + } + try{ + rs.getString(2); + } catch(CobolResultSetException e) { + e.printStackTrace(); + } + try{ + rs.getInt(3); + } catch(CobolResultSetException e) { + e.printStackTrace(); + } + try{ + rs.getDouble(3); + } catch(CobolResultSetException e) { + e.printStackTrace(); + } + } +} +]) + +AT_CHECK([cobj b.cbl]) +AT_CHECK([javac a.java]) +AT_CHECK([java a 2>&1 | grep 'jp.osscons.opensourcecobol.libcobj.ui.CobolResultSetException'], [0], +[jp.osscons.opensourcecobol.libcobj.ui.CobolResultSetException: The result type is not 'double' +jp.osscons.opensourcecobol.libcobj.ui.CobolResultSetException: The result type is not 'String' +jp.osscons.opensourcecobol.libcobj.ui.CobolResultSetException: The result type is not 'int' +jp.osscons.opensourcecobol.libcobj.ui.CobolResultSetException: The result type is not 'String' +jp.osscons.opensourcecobol.libcobj.ui.CobolResultSetException: The result type is not 'int' +jp.osscons.opensourcecobol.libcobj.ui.CobolResultSetException: The result type is not 'double' +]) +AT_CLEANUP \ No newline at end of file