diff --git a/CHANGELOG.md b/CHANGELOG.md index d2dd0320..d7705e25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [1.0.15] - 2023-09-29 +### Added +- Add new intrinsic functions + - EXCEPTION-FILE (#218) + - EXCEPTION-LOCATION (218) + - EXCEPTION-STATEMENT (#221) + - EXCEPTION-STATUS (#221) + - FRACTION-PART (#224) +- Add `-Wredefinition` option (#223) +- Implement `FD` with `EXTERNAL` clause (#222) +- Add a guideline for contributing (#226) +### Fixed +- Fix a build error on some platforms (#225) ## [1.0.14] - 2023-08-31 ### Added diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..530b9254 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,51 @@ +Thank you for your interest in contributing to opensource COBOL 4J. +A summary of how to contribute is below. + +# Issues + +Although any topics related to opensource COBOL 4J can be posted in [Issues](https://github.com/opensourcecobol/opensourcecobol4j/issues), please submit ones written in English or Japanese. + +# Pull Requests + +We will check pull requests that passed all CI checks running both tests and static code analysis. +The static analysis checks whether C and Java source files are formatted using [clang-format](https://clang.llvm.org/docs/ClangFormat.html) and [google-java-format](https://github.com/google/google-java-format) respectively, and whether [PMD](https://pmd.github.io/) finds no error and warning in Java source files. + +The below sections describe how to setup and run static code analysis. + +## Setup static analysis tools + +### clang-format + +Run `sudo apt install clang-format` in Ubuntu to install `clang-format`. + +### google-java-format + +Run the following command to download `google-java-format`: +```sh +curl -L -o google-java-format.jar https://github.com/google/google-java-format/releases/download/v1.15.0/google-java-format-1.15.0-all-deps.jar +``` +Then set the environment variable `PATH_GOOGLE_JAVA_FORMAT` to the file path of the jar file. + +### PMD + +Run the following commands to install `PMD`: +```sh +curl -L -o pmd-bin-6.52.0.zip https://github.com/pmd/pmd/releases/download/pmd_releases%2F6.52.0/pmd-bin-6.52.0.zip +unzip pmd-bin-6.52.0.zip +mv pmd-bin-6.52 /usr/local/bin/ +rm pmd-bin-6.52.0.zip +``` + +## Run static analysis + +### clang-format and google-java-format + +Run `./format` in the top directory of opensource COBOL 4J. +If you want to make sure all files are formatted, run `./check-format` in the top directory of opensource COBOL 4J. + +### PMD + +Run the following command in the top directory of opensource COBOL 4J: +``` +/usr/local/bin/pmd-bin-6.52.0/bin/run.sh -d libcobj/src -R .github/ruleset.xml -f text +``` diff --git a/CONTRIBUTING_JP.md b/CONTRIBUTING_JP.md new file mode 100644 index 00000000..3aae6638 --- /dev/null +++ b/CONTRIBUTING_JP.md @@ -0,0 +1,51 @@ +opensource COBOL 4Jへのコントリビュートを検討頂きありがとうございます。 +下記にコントリビュートの手順を示します。 + +# Issues + +opensource COBOL 4Jに関するトピックを投稿してください。ただし、英語か日本語での記載をお願いします。 + +# Pull Requests +CIはテストとコードの静的解析を実行します。 +CIの静的解析はCとJavaのソースコードがそれぞれ[clang-format](https://clang.llvm.org/docs/ClangFormat.html) and [google-java-format](https://github.com/google/google-java-format)で整形されているか、 +[PMD](https://pmd.github.io/)によるJavaソースコードの静的解析でエラーや警告が表示されないかをチェックします。 + +下記にそれぞれのツールのセットアップと使用方法を説明します。 + +## セットアップ + +### clang-format + +Ubuntuでは`sudo apt install clang-format`コマンドを実行すれば`clang-format`をインストールできます。 + +### google-java-format + +下記のコマンドを実行して`google-java-format`をダウンロードしてください。 +```sh +curl -L -o google-java-format.jar https://github.com/google/google-java-format/releases/download/v1.15.0/google-java-format-1.15.0-all-deps.jar +``` +さらに環境変数`PATH_GOOGLE_JAVA_FORMAT`に上記のjarファイルのファイルパスを設定してください。 + +### PMD + +下記のコマンドを実行して`PMD`をインストールしてください。 +```sh +curl -L -o pmd-bin-6.52.0.zip https://github.com/pmd/pmd/releases/download/pmd_releases%2F6.52.0/pmd-bin-6.52.0.zip +unzip pmd-bin-6.52.0.zip +mv pmd-bin-6.52 /usr/local/bin/ +rm pmd-bin-6.52.0.zip +``` + +## 静的解析の実行 + +### clang-formatとgoogle-java-format + +opensource COBOL 4Jのトップディレクトリで`./format`を実行してください。 +`./check-format`を実行することで、フォーマットが完了したかを確認できます。 + +### PMD + +opensource COBOL 4Jのトップディレクトリで下記のコマンドを実行してください。 +``` +/usr/local/bin/pmd-bin-6.52.0/bin/run.sh -d libcobj/src -R .github/ruleset.xml -f text +``` diff --git a/ChangeLog b/ChangeLog index 80cc2c72..9eccad64 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2023-09-29 OSS Consortium + + * opensource COBOL 4J v1.0.15 released. + 2023-08-31 OSS Consortium * opensource COBOL 4J v1.0.14 released. diff --git a/NEWS b/NEWS index 7487264b..2aac7492 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,26 @@ NEWS - user visible changes -*- outline -*- ----------------------------------------------------------------------- +* opensource COBOL 4J 1.0.15 + +** New Features + (1) Add new intrinsic functions + (a) EXCEPTION-FILE + (b) EXCEPTION-LOCATION + (c) EXCEPTION-STATEMENT + (d) EXCEPTION-STATUS + (e) FRACTION-PART + (2) Add -Wredefinition option + (3) Implement FD with EXTERNAL clause + +** Bug fixes + (1) Fix a build error on some platforms + +** Miscellaneous + (1) Add a guidelines for contributing + +----------------------------------------------------------------------- + * opensource COBOL 4J 1.0.14 ** New Features diff --git a/README.md b/README.md index 7c7eccbd..d5319c81 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ rw 4 0 4 0 0 0 0 0 0 REPORT total 21 0 21 0 0 0 0 0 0 ``` -# Contributors +# Contributing -See https://github.com/opensourcecobol/opensourcecobol4j/graphs/contributors +Guidelines for contributing to opensource COBOL 4J can be found in [CONTRIBUTING.md](./CONTRIBUTING.md). +Contributors are listed in https://github.com/opensourcecobol/opensourcecobol4j/graphs/contributors diff --git a/README_JP.md b/README_JP.md index 03a0aca8..cb053530 100644 --- a/README_JP.md +++ b/README_JP.md @@ -81,6 +81,7 @@ rw 4 0 4 0 0 0 0 0 0 REPORT total 21 0 21 0 0 0 0 0 0 ``` -# コントリビュータ +# コントリビューㇳ -https://github.com/opensourcecobol/opensourcecobol4j/graphs/contributors を参照してください. +コントリビュータの一覧は https://github.com/opensourcecobol/opensourcecobol4j/graphs/contributors に掲載されています。 +コントリビュータ向けのガイドラインは[CONTRIBUTING_JP.md](./CONTRIBUTING_JP.md)を参照してください。 \ No newline at end of file diff --git a/cobj/codegen.c b/cobj/codegen.c index 27d3edd5..e06dd3cf 100644 --- a/cobj/codegen.c +++ b/cobj/codegen.c @@ -1408,6 +1408,7 @@ static void joutput_param(cb_tree x, int id) { struct cb_alphabet_name *abp; struct cb_alphabet_name *rbp; cb_tree l; + struct literal_list *ll; int n; int extrefs; int sav_stack_id; @@ -1490,8 +1491,8 @@ static void joutput_param(cb_tree x, int id) { joutput("%s%s", CB_PREFIX_FILE, CB_FILE(x)->cname); break; case CB_TAG_LITERAL: - struct literal_list *l = lookup_literal(x); - joutput_const_identifier(l); + ll = lookup_literal(x); + joutput_const_identifier(ll); break; case CB_TAG_FIELD: /* TODO: remove me */ @@ -4012,13 +4013,20 @@ static void joutput_file_initialization(struct cb_file *f) { joutput_line (" byte_%s%s[i] = '0;'"); joutput_line ("}"); }*/ + if (f->external) { + joutput_line("%s%s = CobolFile.getExternalFile(\"%s\");", CB_PREFIX_FILE, + f->cname, f->cname); + joutput_line("if(%s%s == null) {", CB_PREFIX_FILE, f->cname); + joutput_indent_level += 2; + } joutput_line("%s%s = CobolFileFactory.makeCobolFileInstance(", CB_PREFIX_FILE, f->cname); joutput_line("/* select_name = */ \"%s\",", f->name); if (f->external && !f->file_status) { - joutput_line("/* file_status = */ cob_external_addr (\"%s%s_status\", 4),", - CB_PREFIX_FILE, f->cname); + joutput_line("/* file_status = */ CobolFile.getExternalFileStatus " + "(\"%s\"),", + f->cname); } else { joutput_line("/* file_status = */ %s%s_status,", CB_PREFIX_FILE, f->cname); } @@ -4076,26 +4084,15 @@ static void joutput_file_initialization(struct cb_file *f) { joutput_line(");"); if (f->external) { - // joutput_line ("%s%s = CobolExternal.getFileAddress (\"%s\");", - // CB_PREFIX_FILE, f->cname, f->cname); - joutput_line("if (CobolExternal.initialExternal)"); - joutput_indent("{"); - if (f->linage) { - joutput_line("%s%s.setLinorkeyptr(new Linage());", CB_PREFIX_FILE, - f->cname); - } - } else { - // joutput_line ("if (%s%s == null)", CB_PREFIX_FILE, f->cname); - // joutput_indent ("{"); - // joutput_line ("%s%s = new CobolFile();", CB_PREFIX_FILE, f->cname); - if (f->linage) { - joutput_line("%s%s.setLinorkeyptr(new Linage());", CB_PREFIX_FILE, - f->cname); - } - // joutput_indent ("}"); + joutput_line("CobolFile.putExternalFile(\"%s\", %s%s);", f->cname, + CB_PREFIX_FILE, f->cname); + joutput_indent_level -= 2; + joutput_line("}"); } if (f->linage) { + joutput_line("%s%s.setLinorkeyptr(new Linage());", CB_PREFIX_FILE, + f->cname); joutput_line("lingptr = (Linage)(%s%s.getLinorkeyptr());", CB_PREFIX_FILE, f->cname); joutput_prefix(); @@ -4135,9 +4132,6 @@ static void joutput_file_initialization(struct cb_file *f) { joutput_line("lingptr.setLinTop(0);"); joutput_line("lingptr.setLinBot(0);"); } - if (f->external) { - joutput_indent("}"); - } } /* diff --git a/cobj/warning-help.def b/cobj/warning-help.def index 4d331b8f..f8d890d5 100644 --- a/cobj/warning-help.def +++ b/cobj/warning-help.def @@ -23,6 +23,9 @@ /* CB_WARNDEF (var, name, wall, doc) */ +CB_WARNDEF (cb_warn_redefinition, "redefinition", 1, + N_("Warn incompatible redefinition of data items")) + CB_WARNDEF (cb_warn_parentheses, "parentheses", 1, N_("Warn lack of parentheses around AND within OR")) diff --git a/configure b/configure index 483820a2..537badb0 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for opensource COBOL 4J 1.0.14. +# Generated by GNU Autoconf 2.71 for opensource COBOL 4J 1.0.15. # # Report bugs to . # @@ -620,9 +620,9 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='opensource COBOL 4J' -PACKAGE_TARNAME='opensource-cobol-4j-1.0.14' -PACKAGE_VERSION='1.0.14' -PACKAGE_STRING='opensource COBOL 4J 1.0.14' +PACKAGE_TARNAME='opensource-cobol-4j-1.0.15' +PACKAGE_VERSION='1.0.15' +PACKAGE_STRING='opensource COBOL 4J 1.0.15' PACKAGE_BUGREPORT='ws-opensource-cobol-contact@osscons.jp' PACKAGE_URL='' @@ -1414,7 +1414,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures opensource COBOL 4J 1.0.14 to adapt to many kinds of systems. +\`configure' configures opensource COBOL 4J 1.0.15 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1464,7 +1464,7 @@ Fine tuning of the installation directories: --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root - [DATAROOTDIR/doc/opensource-cobol-4j-1.0.14] + [DATAROOTDIR/doc/opensource-cobol-4j-1.0.15] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] @@ -1486,7 +1486,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of opensource COBOL 4J 1.0.14:";; + short | recursive ) echo "Configuration of opensource COBOL 4J 1.0.15:";; esac cat <<\_ACEOF @@ -1617,7 +1617,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -opensource COBOL 4J configure 1.0.14 +opensource COBOL 4J configure 1.0.15 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2105,7 +2105,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by opensource COBOL 4J $as_me 1.0.14, which was +It was created by opensource COBOL 4J $as_me 1.0.15, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3403,8 +3403,8 @@ fi # Define the identity of the package. - PACKAGE='opensource-cobol-4j-1.0.14' - VERSION='1.0.14' + PACKAGE='opensource-cobol-4j-1.0.15' + VERSION='1.0.15' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -25367,7 +25367,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by opensource COBOL 4J $as_me 1.0.14, which was +This file was extended by opensource COBOL 4J $as_me 1.0.15, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -25435,7 +25435,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -opensource COBOL 4J config.status 1.0.14 +opensource COBOL 4J config.status 1.0.15 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 0f576d7a..86ff3abe 100644 --- a/configure.ac +++ b/configure.ac @@ -19,7 +19,7 @@ AC_PREREQ(2.59) -AC_INIT([opensource COBOL 4J],[1.0.14],[ws-opensource-cobol-contact@osscons.jp],[opensource-cobol-4j-1.0.14]) +AC_INIT([opensource COBOL 4J],[1.0.15],[ws-opensource-cobol-contact@osscons.jp],[opensource-cobol-4j-1.0.15]) AC_CONFIG_SRCDIR([libcobj.h]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_TESTDIR([tests]) diff --git a/format b/format index cdb1c15e..8bb30de8 100755 --- a/format +++ b/format @@ -1,3 +1,3 @@ #!/bin/bash cd libcobj && ./format -cd cobj && ./format +cd ../cobj && ./format diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/call/CobolResolve.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/call/CobolResolve.java index 76f2e197..c57dfffa 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/call/CobolResolve.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/call/CobolResolve.java @@ -41,13 +41,19 @@ public class CobolResolve { /** プログラム名とCobolRunnableインスタンスの対応表 */ private static Map callTable; + /** ポインタ(UUID)のCobolRunnableインスタンスの対応表 */ private static Map pointerTable; + + public static Map cobException; + /** 名前の変換方法(小文字か大文字)を示す変数 */ private static int name_convert; + // TODO resolve_pathsの利用方法 /** システムで設定された区切り文字で区切られた0個以上のパス 動的に読み込むクラスファイルを検索する場所を示す. */ private static List resolve_paths; + /** システムで設定された区切り文字で区切られた0個以上のパス 動的に読み込むクラスファイルを検索するパッケージ名を示す. */ private static List package_paths; @@ -57,6 +63,154 @@ public class CobolResolve { name_convert = 0; resolve_paths = new ArrayList(); package_paths = new ArrayList(); + cobException = new HashMap<>(); + + cobException.put(0xFFFF, "EC-ALL"); + cobException.put(0x0100, "EC-ARGUMENT"); + cobException.put(0x0101, "EC-ARGUMENT-FUNCTION"); + cobException.put(0x0102, "EC-ARGUMENT-IMP"); + cobException.put(0x0200, "EC-BOUND"); + cobException.put(0x0201, "EC-BOUND-IMP"); + cobException.put(0x0202, "EC-BOUND-ODO"); + cobException.put(0x0203, "EC-BOUND-OVERFLOW"); + cobException.put(0x0204, "EC-BOUND-PTR"); + cobException.put(0x0205, "EC-BOUND-REF-MOD"); + cobException.put(0x0206, "EC-BOUND-SET"); + cobException.put(0x0207, "EC-BOUND-SUBSCRIPT"); + cobException.put(0x0208, "EC-BOUND-TABLE-LIMIT"); + cobException.put(0x0300, "EC-DATA"); + cobException.put(0x0301, "EC-DATA-CONVERSION"); + cobException.put(0x0302, "EC-DATA-IMP"); + cobException.put(0x0303, "EC-DATA-INCOMPATIBLE"); + cobException.put(0x0304, "EC-DATA-INTEGRITY"); + cobException.put(0x0305, "EC-DATA-PTR-NULL"); + cobException.put(0x0306, "EC-DATA-INFINITY"); + cobException.put(0x0307, "EC-DATA-NEGATIVE-INFINITY"); + cobException.put(0x0308, "EC-DATA-NOT_A_NUMBER"); + cobException.put(0x0400, "EC-FLOW"); + cobException.put(0x0401, "EC-FLOW-GLOBAL-EXIT"); + cobException.put(0x0402, "EC-FLOW-GLOBAL-GOBACK"); + cobException.put(0x0403, "EC-FLOW-IMP"); + cobException.put(0x0404, "EC-FLOW-RELEASE"); + cobException.put(0x0405, "EC-FLOW-REPORT"); + cobException.put(0x0406, "EC-FLOW-RETURN"); + cobException.put(0x0407, "EC-FLOW-SEARCH"); + cobException.put(0x0408, "EC-FLOW-USE"); + cobException.put(0x0500, "EC-I-O"); + cobException.put(0x0501, "EC-I-O-AT-END"); + cobException.put(0x0502, "EC-I-O-EOP"); + cobException.put(0x0503, "EC-I-O-EOP-OVERFLOW"); + cobException.put(0x0504, "EC-I-O-FILE-SHARING"); + cobException.put(0x0505, "EC-I-O-IMP"); + cobException.put(0x0506, "EC-I-O-INVALID-KEY"); + cobException.put(0x0507, "EC-I-O-LINAGE"); + cobException.put(0x0508, "EC-I-O-LOGIC-ERROR"); + cobException.put(0x0509, "EC-I-O-PERMANENT-ERROR"); + cobException.put(0x050A, "EC-I-O-RECORD-OPERATION"); + cobException.put(0x0600, "EC-IMP"); + cobException.put(0x0601, "EC-IMP-ACCEPT"); + cobException.put(0x0602, "EC-IMP-DISPLAY"); + cobException.put(0x0700, "EC-LOCALE"); + cobException.put(0x0701, "EC-LOCALE-IMP"); + cobException.put(0x0702, "EC-LOCALE-INCOMPATIBLE"); + cobException.put(0x0703, "EC-LOCALE-INVALID"); + cobException.put(0x0704, "EC-LOCALE-INVALID-PTR"); + cobException.put(0x0705, "EC-LOCALE-MISSING"); + cobException.put(0x0706, "EC-LOCALE-SIZE"); + cobException.put(0x0800, "EC-OO"); + cobException.put(0x0801, "EC-OO-CONFORMANCE"); + cobException.put(0x0802, "EC-OO-EXCEPTION"); + cobException.put(0x0803, "EC-OO-IMP"); + cobException.put(0x0804, "EC-OO-METHOD"); + cobException.put(0x0805, "EC-OO-NULL"); + cobException.put(0x0806, "EC-OO-RESOURCE"); + cobException.put(0x0807, "EC-OO-UNIVERSAL"); + cobException.put(0x0900, "EC-ORDER"); + cobException.put(0x0901, "EC-ORDER-IMP"); + cobException.put(0x0902, "EC-ORDER-NOT-SUPPORTED"); + cobException.put(0x0A00, "EC-OVERFLOW"); + cobException.put(0x0A01, "EC-OVERFLOW-IMP"); + cobException.put(0x0A02, "EC-OVERFLOW-STRING"); + cobException.put(0x0A03, "EC-OVERFLOW-UNSTRING"); + cobException.put(0x0B00, "EC-PROGRAM"); + cobException.put(0x0B01, "EC-PROGRAM-ARG-MISMATCH"); + cobException.put(0x0B02, "EC-PROGRAM-ARG-OMITTED"); + cobException.put(0x0B03, "EC-PROGRAM-CANCEL-ACTIVE"); + cobException.put(0x0B04, "EC-PROGRAM-IMP"); + cobException.put(0x0B05, "EC-PROGRAM-NOT-FOUND"); + cobException.put(0x0B06, "EC-PROGRAM-PTR-NULL"); + cobException.put(0x0B07, "EC-PROGRAM-RECURSIVE-CALL"); + cobException.put(0x0B08, "EC-PROGRAM-RESOURCES"); + cobException.put(0x0C00, "EC-RAISING"); + cobException.put(0x0C01, "EC-RAISING-IMP"); + cobException.put(0x0C02, "EC-RAISING-NOT-SPECIFIED"); + cobException.put(0x0D00, "EC-RANGE"); + cobException.put(0x0D01, "EC-RANGE-IMP"); + cobException.put(0x0D02, "EC-RANGE-INDEX"); + cobException.put(0x0D03, "EC-RANGE-INSPECT-SIZE"); + cobException.put(0x0D04, "EC-RANGE-INVALID"); + cobException.put(0x0D05, "EC-RANGE-PERFORM-VARYING"); + cobException.put(0x0D06, "EC-RANGE-PTR"); + cobException.put(0x0D07, "EC-RANGE-SEARCH-INDEX"); + cobException.put(0x0D08, "EC-RANGE-SEARCH-NO-MATCH"); + cobException.put(0x0E00, "EC-REPORT"); + cobException.put(0x0E01, "EC-REPORT-ACTIVE"); + cobException.put(0x0E02, "EC-REPORT-COLUMN-OVERLAP"); + cobException.put(0x0E03, "EC-REPORT-FILE-MODE"); + cobException.put(0x0E04, "EC-REPORT-IMP"); + cobException.put(0x0E05, "EC-REPORT-INACTIVE"); + cobException.put(0x0E06, "EC-REPORT-LINE-OVERLAP"); + cobException.put(0x0E08, "EC-REPORT-NOT-TERMINATED"); + cobException.put(0x0E09, "EC-REPORT-PAGE-LIMIT"); + cobException.put(0x0E0A, "EC-REPORT-PAGE-WIDTH"); + cobException.put(0x0E0B, "EC-REPORT-SUM-SIZE"); + cobException.put(0x0E0C, "EC-REPORT-VARYING"); + cobException.put(0x0F00, "EC-SCREEN"); + cobException.put(0x0F01, "EC-SCREEN-FIELD-OVERLAP"); + cobException.put(0x0F02, "EC-SCREEN-IMP"); + cobException.put(0x0F03, "EC-SCREEN-ITEM-TRUNCATED"); + cobException.put(0x0F04, "EC-SCREEN-LINE-NUMBER"); + cobException.put(0x0F05, "EC-SCREEN-STARTING-COLUMN"); + cobException.put(0x1000, "EC-SIZE"); + cobException.put(0x1001, "EC-SIZE-ADDRESS"); + cobException.put(0x1002, "EC-SIZE-EXPONENTIATION"); + cobException.put(0x1003, "EC-SIZE-IMP"); + cobException.put(0x1004, "EC-SIZE-OVERFLOW"); + cobException.put(0x1005, "EC-SIZE-TRUNCATION"); + cobException.put(0x1006, "EC-SIZE-UNDERFLOW"); + cobException.put(0x1007, "EC-SIZE-ZERO-DIVIDE"); + cobException.put(0x1100, "EC-SORT-MERGE"); + cobException.put(0x1101, "EC-SORT-MERGE-ACTIVE"); + cobException.put(0x1102, "EC-SORT-MERGE-FILE-OPEN"); + cobException.put(0x1103, "EC-SORT-MERGE-IMP"); + cobException.put(0x1104, "EC-SORT-MERGE-RELEASE"); + cobException.put(0x1105, "EC-SORT-MERGE-RETURN"); + cobException.put(0x1106, "EC-SORT-MERGE-SEQUENCE"); + cobException.put(0x1200, "EC-STORAGE"); + cobException.put(0x1201, "EC-STORAGE-IMP"); + cobException.put(0x1202, "EC-STORAGE-NOT-ALLOC"); + cobException.put(0x1203, "EC-STORAGE-NOT-AVAIL"); + cobException.put(0x1300, "EC-USER"); + cobException.put(0x1400, "EC-VALIDATE"); + cobException.put(0x1401, "EC-VALIDATE-CONTENT"); + cobException.put(0x1402, "EC-VALIDATE-FORMAT"); + cobException.put(0x1403, "EC-VALIDATE-IMP"); + cobException.put(0x1404, "EC-VALIDATE-RELATION"); + cobException.put(0x1405, "EC-VALIDATE-VARYING"); + cobException.put(0x1500, "EC-FUNCTION"); + cobException.put(0x1501, "EC-FUNCTION-NOT-FOUND"); + cobException.put(0x1502, "EC-FUNCTION-PTR-INVALID"); + cobException.put(0x1503, "EC-FUNCTION-PTR-NULL"); + cobException.put(0x1600, "EC-XML"); + cobException.put(0x1601, "EC-XML-CODESET"); + cobException.put(0x1602, "EC-XML-CODESET-CONVERSION"); + cobException.put(0x1603, "EC-XML-COUNT"); + cobException.put(0x1604, "EC-XML-DOCUMENT-TYPE"); + cobException.put(0x1605, "EC-XML-IMPLICIT-CLOSE"); + cobException.put(0x1606, "EC-XML-INVALID"); + cobException.put(0x1607, "EC-XML-NAMESPACE"); + cobException.put(0x1608, "EC-XML-STACKED-OPEN"); + cobException.put(0x1609, "EC-XML-RANGE"); } /** 初期化を行う */ diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/common/CobolIntrinsic.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/common/CobolIntrinsic.java index 011a866d..6a6dc6d3 100755 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/common/CobolIntrinsic.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/common/CobolIntrinsic.java @@ -19,6 +19,7 @@ package jp.osscons.opensourcecobol.libcobj.common; import java.math.BigDecimal; +import java.time.LocalDateTime; import java.util.Arrays; import java.util.Calendar; import java.util.Random; @@ -31,6 +32,7 @@ import jp.osscons.opensourcecobol.libcobj.exceptions.CobolExceptionId; import jp.osscons.opensourcecobol.libcobj.exceptions.CobolRuntimeException; import jp.osscons.opensourcecobol.libcobj.exceptions.CobolStopRunException; +import jp.osscons.opensourcecobol.libcobj.file.CobolFile; public class CobolIntrinsic { @@ -44,6 +46,8 @@ public class CobolIntrinsic { private static AbstractCobolField currField = null; private static AbstractCobolField[] calcField = new AbstractCobolField[DEPTH_LEVEL]; private static Random random = new Random(); + private static byte[] localeBuff; + private static final byte[] byteArray00 = "00".getBytes(); /** libcob/intrinsicのmake_double_entryの実装 */ private static void makeDoubleEntry() { @@ -1770,4 +1774,279 @@ public static AbstractCobolField funcConcatenate( } return currField; } + + /** + * cob_intr_date_to_yyyymmddの実装 + * + * @param params + * @param fields + * @return + */ + public static AbstractCobolField funcDateToYyyymmdd(int params, AbstractCobolField... fields) { + int year; + int mmdd; + int interval; + int xqtyear; + int maxyear; + LocalDateTime timeptr; + + CobolFieldAttribute attr = + new CobolFieldAttribute(CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 8, 0, 0, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(4, (CobolDataStorage) null, attr); + makeFieldEntry(field); + year = fields[0].getInt(); + mmdd = year % 10000; + year /= 10000; + if (params > 1) { + interval = fields[1].getInt(); + } else { + interval = 50; + } + if (params > 2) { + xqtyear = fields[2].getInt(); + } else { + timeptr = CobolUtil.localtime(); + xqtyear = 1900 + timeptr.getDayOfYear(); + } + if (year < 0 || year > 999999) { + CobolRuntimeException.setException(CobolExceptionId.COB_EC_ARGUMENT_FUNCTION); + currField.setInt(0); + return currField; + } + if (xqtyear < 1601 || xqtyear > 9999) { + CobolRuntimeException.setException(CobolExceptionId.COB_EC_ARGUMENT_FUNCTION); + currField.setInt(0); + return currField; + } + maxyear = xqtyear + interval; + if (maxyear < 1700 || maxyear > 9999) { + CobolRuntimeException.setException(CobolExceptionId.COB_EC_ARGUMENT_FUNCTION); + currField.setInt(0); + return currField; + } + if (maxyear % 100 >= year) { + year += 100 * (maxyear / 100); + } else { + year += 100 * ((maxyear / 100) - 1); + } + year *= 10000; + year += mmdd; + currField.setInt(year); + return currField; + } + + /** + * cob_intr_day_to_yyyydddの実装 + * + * @param params + * @param fields + * @return + */ + public static AbstractCobolField funcDayToYyyyddd(int params, AbstractCobolField... fields) { + int year; + int days; + int interval; + int xqtyear; + int maxyear; + LocalDateTime timeptr; + + CobolFieldAttribute attr = + new CobolFieldAttribute(CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 8, 0, 0, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(4, (CobolDataStorage) null, attr); + makeFieldEntry(field); + year = fields[0].getInt(); + days = year % 1000; + year /= 1000; + if (params > 1) { + interval = fields[1].getInt(); + } else { + interval = 50; + } + if (params > 2) { + xqtyear = fields[2].getInt(); + } else { + timeptr = CobolUtil.localtime(); + xqtyear = 1900 + timeptr.getDayOfYear(); + } + + if (year < 0 || year > 999999) { + CobolRuntimeException.setException(CobolExceptionId.COB_EC_ARGUMENT_FUNCTION); + currField.setInt(0); + return currField; + } + if (xqtyear < 1601 || xqtyear > 9999) { + CobolRuntimeException.setException(CobolExceptionId.COB_EC_ARGUMENT_FUNCTION); + currField.setInt(0); + return currField; + } + maxyear = xqtyear + interval; + if (maxyear < 1700 || maxyear > 9999) { + CobolRuntimeException.setException(CobolExceptionId.COB_EC_ARGUMENT_FUNCTION); + currField.setInt(0); + return currField; + } + if (maxyear % 100 >= year) { + year += 100 * (maxyear / 100); + } else { + year += 100 * ((maxyear / 100) - 1); + } + year *= 1000; + year += days; + currField.setInt(year); + return currField; + } + + /** + * cob_intr_exception_fileの実装 + * + * @return + */ + public static AbstractCobolField funcExceptionFile() { + int flen; + byte[] data; + + CobolFieldAttribute attr = + new CobolFieldAttribute(CobolFieldAttribute.COB_TYPE_ALPHANUMERIC, 0, 0, 0, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(0, (CobolDataStorage) null, attr); + if (CobolRuntimeException.getException() == 0 + || (CobolRuntimeException.getExceptionCode() & 0x0500) != 0x0500) { + field.setSize(2); + makeFieldEntry(field); + currField.memcpy(byteArray00, 2); + } else { + flen = CobolFile.errorFile.getSelectName().length(); + field.setSize(flen + 2); + makeFieldEntry(field); + data = new byte[2 + flen]; + System.arraycopy(CobolFile.errorFile.getFileStatus(), 0, data, 0, 2); + System.arraycopy(CobolFile.errorFile.getSelectName().getBytes(), 0, data, 2, flen); + currField.setDataStorage(new CobolDataStorage(data)); + } + return currField; + } + + /** + * cob_intr_exception_locationの実装 + * + * @return + */ + public static AbstractCobolField funcExceptionLocation() { + String buff; + + CobolFieldAttribute attr = + new CobolFieldAttribute(CobolFieldAttribute.COB_TYPE_ALPHANUMERIC, 0, 0, 0, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(0, (CobolDataStorage) null, attr); + currField = field; + if (CobolRuntimeException.getException() != 1 + || CobolRuntimeException.getOrigProgramId() == null) { + field.setSize(1); + makeFieldEntry(field); + currField.getDataStorage().setByte(0, ' '); + return currField; + } + if (CobolRuntimeException.getOrigSection() != null + && CobolRuntimeException.getOrigParagragh() != null) { + buff = + String.format( + "%s; %s OF %s; %d", + CobolRuntimeException.getOrigProgramId(), + CobolRuntimeException.getOrigParagragh(), + CobolRuntimeException.getOrigSection(), + CobolRuntimeException.getOrigLine()); + } else if (CobolRuntimeException.getOrigSection() != null) { + buff = + String.format( + "%s; %s; %d", + CobolRuntimeException.getOrigProgramId(), + CobolRuntimeException.getOrigSection(), + CobolRuntimeException.getOrigLine()); + } else if (CobolRuntimeException.getOrigParagragh() != null) { + buff = + String.format( + "%s; %s; %d", + CobolRuntimeException.getOrigProgramId(), + CobolRuntimeException.getOrigParagragh(), + CobolRuntimeException.getOrigLine()); + } else { + buff = + String.format( + "%s; ; %d", + CobolRuntimeException.getOrigProgramId(), CobolRuntimeException.getOrigLine()); + } + localeBuff = buff.getBytes(); + field.setSize(localeBuff.length); + currField.setDataStorage(new CobolDataStorage(localeBuff)); + return currField; + } + + /** + * cob_intr_exception_statementの実装 + * + * @return + */ + public static AbstractCobolField funcExceptionStatement() { + CobolFieldAttribute attr = + new CobolFieldAttribute(CobolFieldAttribute.COB_TYPE_ALPHANUMERIC, 0, 0, 0, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(31, (CobolDataStorage) null, attr); + makeFieldEntry(field); + byte[] data; + if (CobolRuntimeException.getExceptionCode() != 0 + && CobolRuntimeException.getOrigStatement() != null) { + data = String.format("%-31s", CobolRuntimeException.getOrigStatement()).getBytes(); + } else { + data = String.format("%-31s", "").getBytes(); + } + currField.setDataStorage(new CobolDataStorage(data)); + return currField; + } + + private static final byte[] CONST_STRING_EXCEPTION_OBJECT = "EXCEPTION-OBJECT".getBytes(); + + /** + * cob_intr_exception_statusの実装 + * + * @return + */ + public static AbstractCobolField funcExceptionStatus() { + byte[] exceptName; + + CobolFieldAttribute attr = + new CobolFieldAttribute(CobolFieldAttribute.COB_TYPE_ALPHANUMERIC, 0, 0, 0, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(31, (CobolDataStorage) null, attr); + makeFieldEntry(field); + byte[] data = String.format("%-31s", "").getBytes(); + currField.setDataStorage(new CobolDataStorage(data)); + if (CobolRuntimeException.getExceptionCode() != 0) { + try { + exceptName = + CobolRuntimeException.getExceptionName(CobolRuntimeException.getExceptionCode()) + .getBytes(); + } catch (NullPointerException e) { + exceptName = CONST_STRING_EXCEPTION_OBJECT; + } + currField.memcpy(exceptName, exceptName.length); + } + return currField; + } + + /** + * cob_intr_fraction_partの実装 + * + * @param srcfield + * @return + */ + public static AbstractCobolField funcFractionPart(AbstractCobolField srcfield) { + CobolFieldAttribute attr = + new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, + 18, + 18, + CobolFieldAttribute.COB_FLAG_HAVE_SIGN, + null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(8, (CobolDataStorage) null, attr); + makeFieldEntry(field); + + currField.moveFrom(srcfield); + return currField; + } } diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/common/CobolUtil.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/common/CobolUtil.java old mode 100644 new mode 100755 index abfc1abc..0155f52e --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/common/CobolUtil.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/common/CobolUtil.java @@ -61,6 +61,10 @@ public class CobolUtil { public static String sourceFile; public static int sourceLine; + public static String currProgramId; + public static String currSection; + public static String currParagraph; + public static String sourceStatement; abstract class HandlerList { public HandlerList next = null; @@ -691,6 +695,13 @@ public static void setLocation( String progId, String sfile, int sline, String csect, String cpara, String cstatement) { CobolUtil.sourceFile = sfile; CobolUtil.sourceLine = sline; + currProgramId = progId; + currSection = csect; + currParagraph = cpara; + sourceLine = sline; + if (cstatement != null) { + sourceStatement = cstatement; + } if (CobolUtil.lineTrace) { System.err.println( String.format( @@ -741,4 +752,24 @@ public static byte[] stringToBytes(String s) { public static byte[] toBytes(byte... bytes) { return bytes; } + + public static String getCurrProgramId() { + return currProgramId; + } + + public static String getCurrSection() { + return currSection; + } + + public static String getCurrParagraph() { + return currParagraph; + } + + public static int getSourceLine() { + return sourceLine; + } + + public static String getSourceStatement() { + return sourceStatement; + } } diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/AbstractCobolField.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/AbstractCobolField.java index 81e32732..1a73b4a4 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/AbstractCobolField.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/AbstractCobolField.java @@ -31,8 +31,10 @@ public abstract class AbstractCobolField { /** データを格納に使用するバイト配列の長さ */ protected int size; + /** データを格納するバイト配列を扱うオブジェクト */ protected CobolDataStorage dataStorage; + /** 変数に関する様々な情報を保持するオブジェクト(符号付か,COMP-3指定かなど) */ protected CobolFieldAttribute attribute; diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolDataStorage.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolDataStorage.java index 900d3ce0..4ab8779a 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolDataStorage.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolDataStorage.java @@ -28,6 +28,7 @@ public class CobolDataStorage { /** データを保存するバイト配列 */ private byte[] data; + /** このクラスの扱うデータが保存する領域のバイト配列中での相対位置 */ private int index; diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolFieldAttribute.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolFieldAttribute.java index 484fd5f2..0d30e9ef 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolFieldAttribute.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolFieldAttribute.java @@ -56,12 +56,16 @@ public class CobolFieldAttribute { /** 変数の種類 */ private int type; + /** 数値の時,桁数を示す */ private int digits; + /** 数値の時,スケールを示す */ private int scale; + /** 様々なフラグ */ private int flags; + /** PICTURE句の文字列 */ private String pic; diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericDoubleField.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericDoubleField.java index 38a40b6a..8765f6e6 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericDoubleField.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericDoubleField.java @@ -40,19 +40,7 @@ public byte[] getBytes() { @Override public String getString() { - CobolFieldAttribute thisAttr = this.getAttribute(); - int flag = thisAttr.isFlagHaveSign() ? CobolFieldAttribute.COB_FLAG_HAVE_SIGN : 0; - CobolFieldAttribute attr = - new CobolFieldAttribute( - CobolFieldAttribute.COB_TYPE_NUMERIC, - thisAttr.getDigits(), - thisAttr.getScale(), - flag, - thisAttr.getPic()); - CobolDataStorage storage = new CobolDataStorage(thisAttr.getDigits()); - CobolNumericField numericField = new CobolNumericField(thisAttr.getDigits(), storage, attr); - numericField.moveFrom(this); - return numericField.getString(); + return String.format("%.18f", this.getDouble()); } @Override diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericField.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericField.java index 168b4a4e..6d2ac2dd 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericField.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolNumericField.java @@ -382,9 +382,7 @@ private void moveBinaryToDisplay(AbstractCobolField field) { private void moveDoubleToDisplay(AbstractCobolField field) { CobolFieldAttribute thisAttr = this.getAttribute(); - double val = Math.abs(field.getDouble() * thisAttr.getScale()); - String formatter = "%0" + thisAttr.getDigits() + "." + thisAttr.getScale() + "f"; - String valString = String.format(formatter, val).replace(".", ""); + double val = Math.abs(field.getDouble()); int startIndex = 0; if (thisAttr.isFlagHaveSign() && thisAttr.isFlagSignLeading() @@ -392,7 +390,7 @@ private void moveDoubleToDisplay(AbstractCobolField field) { startIndex = 1; } CobolDataStorage dstStorage = this.getDataStorage().getSubDataStorage(startIndex); - dstStorage.memcpy(valString, thisAttr.getDigits()); + dstStorage.memcpy(String.valueOf(val), thisAttr.getDigits()); this.putSign(field.getSign() >= 0 ? 1 : -1); } diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/exceptions/CobolRuntimeException.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/exceptions/CobolRuntimeException.java old mode 100644 new mode 100755 index 65b7c2b5..f52278d5 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/exceptions/CobolRuntimeException.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/exceptions/CobolRuntimeException.java @@ -19,10 +19,18 @@ package jp.osscons.opensourcecobol.libcobj.exceptions; import java.util.List; +import jp.osscons.opensourcecobol.libcobj.call.CobolResolve; +import jp.osscons.opensourcecobol.libcobj.common.CobolUtil; /** 実行時エラーを示す例外 */ public class CobolRuntimeException extends RuntimeException { public static int code; + public static int cobException = 0; + public static String origProgramId; + public static String origSection; + public static String origParagraph; + public static int origLine = 0; + public static String origStatement; public static final int COBOL_FITAL_ERROR = 9000; @@ -30,6 +38,7 @@ public class CobolRuntimeException extends RuntimeException { /** エラー番号 */ private int errorCode; + /** エラーメッセージ */ private String message; @@ -70,6 +79,43 @@ public void printStackTrace() { public static void setException(int id) { code = CobolExceptionTabCode.code[id]; - // TODO common.c実装に残りをやる + cobException = 1; + origLine = CobolUtil.getSourceLine(); + origProgramId = CobolUtil.getCurrProgramId(); + origSection = CobolUtil.getCurrSection(); + origParagraph = CobolUtil.getCurrParagraph(); + origStatement = CobolUtil.getSourceStatement(); + } + + public static String getExceptionName(int exceptionCode) { + return CobolResolve.cobException.get(exceptionCode); + } + + public static int getExceptionCode() { + return code; + } + + public static int getException() { + return cobException; + } + + public static String getOrigProgramId() { + return origProgramId; + } + + public static String getOrigSection() { + return origSection; + } + + public static String getOrigParagragh() { + return origParagraph; + } + + public static int getOrigLine() { + return origLine; + } + + public static String getOrigStatement() { + return origStatement; } } diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/file/CobolFile.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/file/CobolFile.java old mode 100644 new mode 100755 index 9d9a7814..fae0918e --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/file/CobolFile.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/file/CobolFile.java @@ -29,7 +29,9 @@ import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import jp.osscons.opensourcecobol.libcobj.common.CobolModule; import jp.osscons.opensourcecobol.libcobj.common.CobolUtil; import jp.osscons.opensourcecobol.libcobj.data.AbstractCobolField; @@ -184,7 +186,7 @@ public class CobolFile { CobolExceptionId.COB_EC_I_O, CobolExceptionId.COB_EC_I_O_IMP }; - protected String select_name; + public String select_name; public byte[] file_status; protected AbstractCobolField assign; protected AbstractCobolField record; @@ -219,6 +221,8 @@ public class CobolFile { protected char file_version; protected static String runtime_buffer; + protected static String name; + protected static byte[] status; public Linage getLinorkeyptr() { return this.linorkeyptr; @@ -747,6 +751,7 @@ public void open(int mode, int sharing, AbstractCobolField fnstatus) { return; } } + // protected long start; // protected long end; @@ -1519,4 +1524,37 @@ public void cob_delete_file(AbstractCobolField fnstatus) { } } } + + public String getSelectName() { + // CobolFile cobolFile = new CobolFile(); + return this.select_name; + } + + public byte[] getFileStatus() { + // CobolFile cobolFile = new CobolFile(); + return this.file_status; + } + + private static Map externalFileStatusTable = new HashMap(); + + public static byte[] getExternalFileStatus(String key) { + byte[] bytes = externalFileStatusTable.get(key); + if (bytes == null) { + bytes = new byte[2]; + bytes[0] = 0; + bytes[1] = 0; + externalFileStatusTable.put(key, bytes); + } + return bytes; + } + + private static Map externalFileTable = new HashMap(); + + public static CobolFile getExternalFile(String key) { + return externalFileTable.get(key); + } + + public static CobolFile putExternalFile(String key, CobolFile value) { + return externalFileTable.put(key, value); + } } diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/file/IndexedCursor.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/file/IndexedCursor.java index 6b313632..d919bae0 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/file/IndexedCursor.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/file/IndexedCursor.java @@ -57,24 +57,34 @@ enum CursorReadOption { public final class IndexedCursor { /** a cursor to the top direction */ private Optional backwardCursor; + /** a cursor to the bottom direction */ private Optional forwardCursor; + /** a connection to the SQLite database */ private Connection conn; + /** firstFetch is true if and only if the cursor has not read any data yet */ private boolean firstFetch; + /** a position in buffers that stores the read data */ private int cursorIndex; + /** one of COB_EQ, COB_LT, COB_LE, COB_GT, COB_GE in CobolIndexedFile.java */ private int comparator; + /** isDuplicate is true if and only if the table key allows duplicates */ private boolean isDuplicate; + /** a key */ private byte[] key; + /** forwardBuffer stores data located to the bottom direction from the first read position */ List forwardBuffer; + /** bakckwardBuffer stores data located to the first direction from the first read position */ List backwardBuffer; + /** the index of the table */ private int tableIndex; diff --git a/tests/Makefile.am b/tests/Makefile.am index 8da71112..51671007 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -147,6 +147,7 @@ command_line_options_DEPENDENCIES = \ command-line-options.src/B.at \ command-line-options.src/list-reserved.at \ command-line-options.src/assign_external.at \ + command-line-options.src/Wredefinition.at \ command-line-options.src/Wparentheses.at \ command-line-options.src/Wcolumn-overflow.at \ command-line-options.src/Wterminator.at \ @@ -186,8 +187,8 @@ misc_DEPENDENCIES = \ misc.src/version-string-in-java.at \ misc.src/comp3-compute.at \ misc.src/index-file-status.at \ - misc.src/comp-n.at - + misc.src/comp-n.at \ + misc.src/fd-external.at EXTRA_DIST = $(srcdir)/package.m4 \ $(TESTS) \ @@ -199,7 +200,6 @@ EXTRA_DIST = $(srcdir)/package.m4 \ $(command_line_options_DEPENDENCIES) \ $(misc_DEPENDENCIES) - DISTCLEANFILES = atconfig all: $(TESTS) diff --git a/tests/Makefile.in b/tests/Makefile.in index 5897a04b..953fc120 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -688,6 +688,7 @@ command_line_options_DEPENDENCIES = \ command-line-options.src/B.at \ command-line-options.src/list-reserved.at \ command-line-options.src/assign_external.at \ + command-line-options.src/Wredefinition.at \ command-line-options.src/Wparentheses.at \ command-line-options.src/Wcolumn-overflow.at \ command-line-options.src/Wterminator.at \ @@ -727,7 +728,8 @@ misc_DEPENDENCIES = \ misc.src/version-string-in-java.at \ misc.src/comp3-compute.at \ misc.src/index-file-status.at \ - misc.src/comp-n.at + misc.src/comp-n.at \ + misc.src/fd-external.at EXTRA_DIST = $(srcdir)/package.m4 \ $(TESTS) \ diff --git a/tests/command-line-options.at b/tests/command-line-options.at index 0070bbc3..df0a0de7 100644 --- a/tests/command-line-options.at +++ b/tests/command-line-options.at @@ -9,6 +9,7 @@ m4_include([B.at]) m4_include([list-reserved.at]) m4_include([assign_external.at]) m4_include([java-package.at]) +m4_include([Wredefinition.at]) m4_include([Wparentheses.at]) m4_include([Wcolumn-overflow.at]) m4_include([Wterminator.at]) diff --git a/tests/command-line-options.src/Wredefinition.at b/tests/command-line-options.src/Wredefinition.at new file mode 100644 index 00000000..023aff5a --- /dev/null +++ b/tests/command-line-options.src/Wredefinition.at @@ -0,0 +1,24 @@ +AT_SETUP([-Wredefinition]) + +AT_DATA([prog.cbl], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 GRP. + 03 A PIC X(5). + 01 B redefines GRP. + 05 C PIC X(5). + 01 C PIC X(5). + PROCEDURE DIVISION. + MAIN-RTN. + STOP RUN. +]) + +AT_CHECK([${COBJ} -Wredefinition prog.cbl], [0], [], +[prog.cbl:10: Warning: Redefinition of 'C' +prog.cbl:9: Warning: 'C' previously defined here +]) + +AT_CHECK([${COBJ} --help | grep '\-Wredefinition' > /dev/null], [0]) +AT_CLEANUP diff --git a/tests/misc.at b/tests/misc.at index af709743..39c0681b 100644 --- a/tests/misc.at +++ b/tests/misc.at @@ -38,4 +38,5 @@ m4_include([exit-perform-cycle.at]) m4_include([version-string-in-java.at]) m4_include([comp3-compute.at]) m4_include([index-file-status.at]) -m4_include([comp-n.at]) \ No newline at end of file +m4_include([comp-n.at]) +m4_include([fd-external.at]) diff --git a/tests/misc.src/fd-external.at b/tests/misc.src/fd-external.at new file mode 100644 index 00000000..78c01f25 --- /dev/null +++ b/tests/misc.src/fd-external.at @@ -0,0 +1,68 @@ +AT_SETUP([FD EXTERNAL]) + +AT_DATA([prog.cbl], [ + identification division. + program-id. prog. + environment division. + input-output section. + file-control. + select sequential-file assign to "sequential.txt" + organization is sequential + file status is sequential-file-status. + data division. + file section. + fd sequential-file is external. + 01 sequential-file-rec pic x(20). + working-storage section. + 01 sequential-file-status pic 99. + 01 command pic x(20). + procedure division. + main-rtn. + open output sequential-file. + move "seq-data" to sequential-file-rec. + move "write-sequential" to command. + call "sub" using command. + close sequential-file. + + open input sequential-file. + move space to sequential-file-rec. + move "read-sequential" to command. + call "sub" using command. + display "sequential-file-rec:" sequential-file-rec. + close sequential-file. + +]) + +AT_DATA([sub.cbl], [ + identification division. + program-id. sub. + environment division. + input-output section. + file-control. + select sequential-file assign to "sequential.txt" + organization is sequential + file status is sequential-file-status. + data division. + file section. + fd sequential-file is external. + 01 sequential-file-rec pic x(20). + working-storage section. + 01 sequential-file-status pic 99. + linkage section. + 01 command pic x(20). + procedure division using command. + main-rtn. + evaluate command + when "read-sequential" + read sequential-file + when "write-sequential" + write sequential-file-rec + end-evaluate. +]) + +AT_CHECK([${COBJ} prog.cbl sub.cbl]) +AT_CHECK([java prog], [0], +[sequential-file-rec:seq-data @&t@ +]) + +AT_CLEANUP diff --git a/tests/run.src/functions.at b/tests/run.src/functions.at index 65d3fb6e..07b08fa6 100644 --- a/tests/run.src/functions.at +++ b/tests/run.src/functions.at @@ -294,7 +294,6 @@ AT_CHECK([java prog], [0], AT_CLEANUP AT_SETUP([FUNCTION DATE-TO-YYYYMMDD]) -AT_CHECK([${SKIP_TEST}]) AT_DATA([prog.cob], [ IDENTIFICATION DIVISION. @@ -335,7 +334,6 @@ AT_CHECK([java prog], [0], AT_CLEANUP AT_SETUP([FUNCTION DAY-TO-YYYYDDD]) -AT_CHECK([${SKIP_TEST}]) AT_DATA([prog.cob], [ IDENTIFICATION DIVISION. @@ -375,8 +373,7 @@ AT_CHECK([java prog], [0], AT_CLEANUP -AT_SETUP([FUNCTION EXCEPTION-FILE]) -AT_CHECK([${SKIP_TEST}]) +AT_SETUP([FUNCTION EXCEPTION-FILE (no text)]) AT_DATA([prog.cob], [ IDENTIFICATION DIVISION. @@ -406,8 +403,38 @@ AT_CHECK([java prog], [0], AT_CLEANUP -AT_SETUP([FUNCTION EXCEPTION-LOCATION]) -AT_CHECK([${SKIP_TEST}]) +AT_SETUP([FUNCTION EXCEPTION-FILE (If text file exists)]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT TEST-FILE ASSIGN "TEXIST" + FILE STATUS IS TEST-STATUS. + DATA DIVISION. + FILE SECTION. + FD TEST-FILE. + 01 TEST-REC PIC X(4). + WORKING-STORAGE SECTION. + 01 TEST-STATUS PIC XX. + PROCEDURE DIVISION. + OPEN OUTPUT TEST-FILE. + DISPLAY FUNCTION EXCEPTION-FILE + END-DISPLAY. + CLOSE TEST-FILE. + STOP RUN. +]) + +AT_CHECK([${COMPILE} prog.cob]) +AT_CHECK([java prog], [0], +[00 +]) + +AT_CLEANUP + +AT_SETUP([FUNCTION EXCEPTION-LOCATION (no text)]) AT_DATA([prog.cob], [ IDENTIFICATION DIVISION. @@ -441,8 +468,42 @@ AT_CHECK([java prog], [0], AT_CLEANUP -AT_SETUP([FUNCTION EXCEPTION-STATEMENT]) -AT_CHECK([${SKIP_TEST}]) +AT_SETUP([FUNCTION EXCEPTION-LOCATION (If text file exists)]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT TEST-FILE ASSIGN "TEXIST" + FILE STATUS IS TEST-STATUS. + DATA DIVISION. + FILE SECTION. + FD TEST-FILE. + 01 TEST-REC PIC X(4). + WORKING-STORAGE SECTION. + 01 TEST-STATUS PIC XX. + PROCEDURE DIVISION. + A00-MAIN SECTION. + A00. + OPEN OUTPUT TEST-FILE. + B00-MAIN SECTION. + B00. + DISPLAY FUNCTION EXCEPTION-LOCATION + NO ADVANCING + END-DISPLAY. + CLOSE TEST-FILE. + STOP RUN. +]) + +AT_CHECK([${COMPILE} -debug prog.cob]) +AT_CHECK([java prog], [0], +[ ]) + +AT_CLEANUP + +AT_SETUP([FUNCTION EXCEPTION-STATEMENT (no text)]) AT_DATA([prog.cob], [ IDENTIFICATION DIVISION. @@ -472,8 +533,38 @@ AT_CHECK([java prog], [0], AT_CLEANUP -AT_SETUP([FUNCTION EXCEPTION-STATUS]) -AT_CHECK([${SKIP_TEST}]) +AT_SETUP([FUNCTION EXCEPTION-STATEMENT (If text file exists)]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT TEST-FILE ASSIGN "TEXIST" + FILE STATUS IS TEST-STATUS. + DATA DIVISION. + FILE SECTION. + FD TEST-FILE. + 01 TEST-REC PIC X(4). + WORKING-STORAGE SECTION. + 01 TEST-STATUS PIC XX. + PROCEDURE DIVISION. + OPEN OUTPUT TEST-FILE. + DISPLAY FUNCTION EXCEPTION-STATEMENT + NO ADVANCING + END-DISPLAY. + CLOSE TEST-FILE. + STOP RUN. +]) + +AT_CHECK([${COMPILE} -debug prog.cob]) +AT_CHECK([java prog], [0], +[ ]) + +AT_CLEANUP + +AT_SETUP([FUNCTION EXCEPTION-STATUS (no text)]) AT_DATA([prog.cob], [ IDENTIFICATION DIVISION. @@ -503,6 +594,37 @@ AT_CHECK([java prog], [0], AT_CLEANUP +AT_SETUP([FUNCTION EXCEPTION-STATUS (If text file exists)]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT TEST-FILE ASSIGN "TEXIST" + FILE STATUS IS TEST-STATUS. + DATA DIVISION. + FILE SECTION. + FD TEST-FILE. + 01 TEST-REC PIC X(4). + WORKING-STORAGE SECTION. + 01 TEST-STATUS PIC XX. + PROCEDURE DIVISION. + OPEN OUTPUT TEST-FILE. + DISPLAY FUNCTION EXCEPTION-STATUS + NO ADVANCING + END-DISPLAY. + CLOSE TEST-FILE. + STOP RUN. +]) + +AT_CHECK([${COMPILE} prog.cob]) +AT_CHECK([java prog], [0], +[ ]) + +AT_CLEANUP + AT_SETUP([FUNCTION EXP]) AT_DATA([prog.cob], [ @@ -552,7 +674,6 @@ AT_CHECK([java prog], [0], AT_CLEANUP AT_SETUP([FUNCTION FRACTION-PART]) -AT_CHECK([${SKIP_TEST}]) AT_DATA([prog.cob], [ IDENTIFICATION DIVISION. @@ -913,8 +1034,7 @@ AT_CHECK([java prog], [0], AT_CLEANUP -AT_SETUP([FUNCTION MIDRANGE]) -AT_CHECK([${SKIP_TEST}]) +AT_SETUP([FUNCTION MIDRANGE(calculation result is negative)]) AT_DATA([prog.cob], [ IDENTIFICATION DIVISION. @@ -934,6 +1054,46 @@ AT_CHECK([java prog], [0], AT_CLEANUP +AT_SETUP([FUNCTION MIDRANGE(calculation result is positive)]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + PROCEDURE DIVISION. + DISPLAY FUNCTION MIDRANGE ( 3 14 0 8 3 ) + END-DISPLAY. + STOP RUN. +]) + +AT_CHECK([${COMPILE} prog.cob]) +AT_CHECK([java prog], [0], +[7.000000000000000000 +]) + +AT_CLEANUP + +AT_SETUP([FUNCTION MIDRANGE(calculation result is decimal)]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + PROCEDURE DIVISION. + DISPLAY FUNCTION MIDRANGE ( 2 2 3 9 ) + END-DISPLAY. + STOP RUN. +]) + +AT_CHECK([${COMPILE} prog.cob]) +AT_CHECK([java prog], [0], +[5.500000000000000000 +]) + +AT_CLEANUP + AT_SETUP([FUNCTION MIN]) AT_DATA([prog.cob], [