From 19fc5c0b0c2c04e46a36a79c7d0fdd6891ba1bea Mon Sep 17 00:00:00 2001 From: Yutaro Sakamoto Date: Wed, 9 Jun 2021 01:38:26 +0000 Subject: [PATCH 1/4] =?UTF-8?q?INDEXED=E4=B8=80=E9=83=A8=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../libcobj/file/CobolIndexedFile.java | 27 ++++++++----- tests/cobol85/report.pl | 40 +++++++++++++++++++ 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/file/CobolIndexedFile.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/file/CobolIndexedFile.java index 0c2b7b1f..9376806d 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/file/CobolIndexedFile.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/file/CobolIndexedFile.java @@ -40,6 +40,7 @@ import com.sleepycat.je.LockMode; import com.sleepycat.je.OperationFailureException; import com.sleepycat.je.OperationResult; +import com.sleepycat.je.OperationStatus; import com.sleepycat.je.Put; import com.sleepycat.je.ReadOptions; @@ -524,7 +525,6 @@ public int readNext(int readOpts) { } else { p.key = new DatabaseEntry( p.last_readkey[p.key_index].getByteArray(0, this.keys[p.key_index].getField().getSize())); - try { result = p.cursor[p.key_index].get(p.key, p.data, Get.SEARCH_GTE, readOptions); } catch(LockConflictException e) { @@ -697,7 +697,7 @@ private int indexed_write_internal(boolean rewrite, int opt) { p.data = new DatabaseEntry(this.record.getDataStorage().getByteArray(0, this.record.getSize())); try { - p.cursor[0].put(p.key, p.data); + p.cursor[0].put(p.key, p.data); } catch (LockConflictException e) { return COB_STATUS_51_RECORD_LOCKED; } @@ -705,9 +705,9 @@ private int indexed_write_internal(boolean rewrite, int opt) { p.data = p.key; Put flags; for (int i = 1; i < this.nkeys; i++) { - if (rewrite && p.rewrite_sec_key[i] == 0) { + /*if (rewrite && p.rewrite_sec_key[i] == 0) { continue; - } + }*/ if (this.keys[i].getFlag() != 0) { flags = Put.OVERWRITE; int dupno = this.get_dupno(i); @@ -715,7 +715,7 @@ private int indexed_write_internal(boolean rewrite, int opt) { p.temp_key.getSubDataStorage(this.keys[0].getField().getSize()).set(dupno); p.data = new DatabaseEntry(p.temp_key.getByteArray(0, this.keys[0].getField().getSize() + 4)); } else { - flags = Put.NO_OVERWRITE; + flags = Put.OVERWRITE; } p.key = DBT_SET(this.keys[i].getField()); @@ -871,6 +871,7 @@ public int rewrite_(int opt) { p.write_cursor_open = false; return COB_STATUS_22_KEY_EXISTS; } + int ret = this.indexed_delete_internal(true); if (ret != COB_STATUS_00_SUCCESS) { @@ -934,22 +935,27 @@ private int indexed_delete_internal(boolean rewrite) { p.key = DBT_SET(this.keys[i].getField()); //TODO offset if (rewrite) { - p.rewrite_sec_key[i] = -1 + //continue; + /*p.rewrite_sec_key[i] = -1 * this.keys[i].getField().getDataStorage().memcmp(p.key.getData(), p.key.getSize()); if (p.rewrite_sec_key[i] == 0) { continue; - } + }*/ } - try { + try { if (this.keys[i].getFlag() == 0) { - p.db[i].delete(null, p.key); + if(p.db[i].delete(null, p.key) == OperationStatus.SUCCESS) { + System.out.println("[dbg j] delete success"); + } else { + System.out.println("[dbg j] delete fail"); + } } else { DatabaseEntry sec_key = p.key; p.cursor[i] = p.db[i].openCursor(null, null); if (p.cursor[i].get(p.key, p.data, Get.SEARCH_GTE, null) == null) { while (sec_key.getSize() == p.key.getSize() && arrayEquals(p.key.getData(), sec_key.getData(), sec_key.getSize())) { - if (arrayEquals(p.data.getData(), p.key.getData(), prim_key.getSize())) { + if (arrayEquals(p.data.getData(), prim_key.getData(), prim_key.getSize())) { p.cursor[i].delete(); } if (p.cursor[i].get(p.key, p.data, Get.NEXT, null) == null) { @@ -970,6 +976,7 @@ && arrayEquals(p.key.getData(), sec_key.getData(), sec_key.getSize())) { } try { + System.out.println("[dbg j] delete primary key"); p.cursor[0].delete(); } catch(LockConflictException e) { if(close_cursor) { diff --git a/tests/cobol85/report.pl b/tests/cobol85/report.pl index b33773f5..56730a10 100644 --- a/tests/cobol85/report.pl +++ b/tests/cobol85/report.pl @@ -68,6 +68,46 @@ $skip{OBNC2M} = 1; +$skip{IX101A}=1; +$skip{IX102A}=1; +$skip{IX103A}=1; +$skip{IX104A}=1; +$skip{IX105A}=1; +$skip{IX106A}=1; +$skip{IX107A}=1; +$skip{IX108A}=1; +$skip{IX109A}=1; +$skip{IX110A}=1; +$skip{IX111A}=1; +$skip{IX112A}=1; +$skip{IX113A}=1; +$skip{IX114A}=1; +$skip{IX115A}=1; +$skip{IX116A}=1; +$skip{IX117A}=1; +$skip{IX118A}=1; +$skip{IX119A}=1; +$skip{IX120A}=1; +$skip{IX121A}=1; +$skip{IX201A}=1; +$skip{IX202A}=1; +$skip{IX203A}=1; +$skip{IX204A}=1; +$skip{IX205A}=1; +$skip{IX206A}=1; +$skip{IX207A}=1; +$skip{IX208A}=1; +$skip{IX209A}=1; +$skip{IX210A}=1; +#$skip{IX211A}=1; +#$skip{IX212A}=1; +$skip{IX213A}=1; +$skip{IX214A}=1; +$skip{IX215A}=1; +$skip{IX216A}=1; +$skip{IX217A}=1; +$skip{IX218A}=1; + open (LOG, "> report.txt") or die; print LOG "Filename total pass fail deleted inspect\n"; print LOG "-------- ----- ---- ---- ------- -------\n"; From b4dda92fd3970ac8cef8dc03a0e8a56d4354affd Mon Sep 17 00:00:00 2001 From: Yutaro Sakamoto Date: Wed, 9 Jun 2021 04:35:02 +0000 Subject: [PATCH 2/4] =?UTF-8?q?INDEXED=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E3=81=AE=E3=83=87=E3=83=BC=E3=82=BF=E3=81=AE=E6=8C=81=E3=81=A1?= =?UTF-8?q?=E6=96=B9=E3=82=92=E5=A4=89=E6=9B=B4=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../libcobj/file/CobolIndexedFile.java | 76 +++++++++---------- .../libcobj/file/IndexedFile.java | 1 + tests/cobol85/report.pl | 74 +++++++++--------- 3 files changed, 75 insertions(+), 76 deletions(-) diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/file/CobolIndexedFile.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/file/CobolIndexedFile.java index 9376806d..788fcfbd 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/file/CobolIndexedFile.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/file/CobolIndexedFile.java @@ -145,6 +145,7 @@ public int open_(String filename, int mode, int sharing) { } p.db = new Database[this.nkeys]; + p.sub_db = new Database[this.nkeys - 1]; p.cursor = new Cursor[this.nkeys]; p.filenamelen = filename.length(); p.last_readkey = new CobolDataStorage[2 * this.nkeys]; @@ -180,6 +181,7 @@ public int open_(String filename, int mode, int sharing) { } else { runtime_buffer = String.format("%s.%d", filename, i); } + String subDbName = String.format("%s.sub.%d", filename, i); DatabaseConfig dbConf = new DatabaseConfig(); if (mode == COB_OPEN_INPUT) { @@ -196,6 +198,9 @@ public int open_(String filename, int mode, int sharing) { if (mode == COB_OPEN_OUTPUT) { try { env.removeDatabase(null, runtime_buffer); + if(i > 0) { + env.removeDatabase(null, subDbName); + } } catch (DatabaseNotFoundException e) { //存在しないDBを削除しようとしたときの例外 //これはエラーとして扱わない @@ -204,6 +209,9 @@ public int open_(String filename, int mode, int sharing) { try { p.db[i] = env.openDatabase(null, runtime_buffer, dbConf); + if(i > 0) { + p.sub_db[i-1] = env.openDatabase(null, subDbName, dbConf); + } } catch (OperationFailureException | EnvironmentFailureException | IllegalStateException | IllegalArgumentException e) { e.printStackTrace(); @@ -269,6 +277,12 @@ public int close_(int opt) { p.db[i].close(); } } + + for(int i=0; i report.txt") or die; print LOG "Filename total pass fail deleted inspect\n"; From 6984c02bc5509586739f2351f91578a05667ffe8 Mon Sep 17 00:00:00 2001 From: Yutaro Sakamoto Date: Thu, 17 Jun 2021 07:14:47 +0000 Subject: [PATCH 3/4] =?UTF-8?q?COBOL85=E3=81=AEFUNCTION=E3=82=92=E3=81=99?= =?UTF-8?q?=E3=81=B9=E3=81=A6=E5=AE=9F=E8=A3=85=E3=81=97=E3=81=9F.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cobc/codegen.c | 2 +- cobc/reserved.c | 142 +- .../libcobj/common/CobolIntrinsic.java | 1494 +++++++++++++++++ .../libcobj/common/CobolUtil.java | 1 + .../libcobj/data/AbstractCobolField.java | 9 +- .../libcobj/data/CobolAlphanumericField.java | 2 + .../libcobj/data/CobolDataStorage.java | 14 +- .../libcobj/data/CobolDecimal.java | 46 +- .../libcobj/data/CobolFieldFactory.java | 2 + .../libcobj/data/CobolNumericBinaryField.java | 2 + .../libcobj/data/CobolNumericField.java | 18 + tests/cobol85/report.pl | 75 +- 12 files changed, 1691 insertions(+), 116 deletions(-) create mode 100644 libcobj/src/jp/osscons/opensourcecobol/libcobj/common/CobolIntrinsic.java diff --git a/cobc/codegen.c b/cobc/codegen.c index 3b619d5d..d9f18f5d 100644 --- a/cobc/codegen.c +++ b/cobc/codegen.c @@ -1361,7 +1361,7 @@ joutput_param (cb_tree x, int id) break; case CB_TAG_BINARY_OP: bp = CB_BINARY_OP (x); - joutput ("cob_intr_binop ("); + joutput ("CobolIntrinsic.intrBinop ("); joutput_param (bp->x, id); joutput (", "); joutput ("%d", bp->op); diff --git a/cobc/reserved.c b/cobc/reserved.c index dcf5b654..0cd66af9 100644 --- a/cobc/reserved.c +++ b/cobc/reserved.c @@ -640,55 +640,55 @@ static const struct reserved reserved_words[] = { static const struct cb_intrinsic_table function_list[] = { { "ABS", 1, 1, CB_INTR_ABS, - "cob_intr_abs", + "CobolIntrinsic.funcAbs", CB_CATEGORY_NUMERIC, 0 }, { "ACOS", 1, 1, CB_INTR_ACOS, - "cob_intr_acos", + "CobolIntrinsic.funcAcos", CB_CATEGORY_NUMERIC, 0 }, { "ANNUITY", 2, 1, CB_INTR_ANNUITY, - "cob_intr_annuity", + "CobolIntrinsic.funcAnnuity", CB_CATEGORY_NUMERIC, 0 }, { "ASIN", 1, 1, CB_INTR_ASIN, - "cob_intr_asin", + "CobolIntrinsic.funcAsin", CB_CATEGORY_NUMERIC, 0 }, { "ATAN", 1, 1, CB_INTR_ATAN, - "cob_intr_atan", + "CobolIntrinsic.funcAtan", CB_CATEGORY_NUMERIC, 0 }, { "BOOLEAN-OF-INTEGER", 2, 0, CB_INTR_BOOLEAN_OF_INTEGER, NULL, CB_CATEGORY_NUMERIC, 0 }, { "BYTE-LENGTH", 1, 1, CB_INTR_BYTE_LENGTH, - "cob_intr_length", + "CobolIntrinsic.funcLength", CB_CATEGORY_NUMERIC, 0 }, { "CHAR", 1, 1, CB_INTR_CHAR, - "cob_intr_char", + "CobolIntrinsic.funcChar", CB_CATEGORY_ALPHANUMERIC, 0 }, { "CHAR-NATIONAL", 1, 0, CB_INTR_CHAR_NATIONAL, NULL, CB_CATEGORY_ALPHANUMERIC, 0 }, { "COMBINED-DATETIME", 2, 1, CB_INTR_COMBINED_DATETIME, - "cob_intr_combined_datetime", + "CobolIntrinsic.funcCombinedDatetime", CB_CATEGORY_NUMERIC, 0 }, { "CONCATENATE", -1, 1, CB_INTR_CONCATENATE, - "cob_intr_concatenate", + "CobolIntrinsic.funcConcatenate", CB_CATEGORY_ALPHANUMERIC, 1 }, { "COS", 1, 1, CB_INTR_COS, - "cob_intr_cos", + "CobolIntrinsic.funcCos", CB_CATEGORY_NUMERIC, 0 }, { "CURRENT-DATE", 0, 1, CB_INTR_CURRENT_DATE, - "cob_intr_current_date", + "CobolIntrinsic.funcCurrentDate", CB_CATEGORY_ALPHANUMERIC, 1 }, { "DATE-OF-INTEGER", 1, 1, CB_INTR_DATE_OF_INTEGER, - "cob_intr_date_of_integer", + "CobolIntrinsic.funcDateOfInteger", CB_CATEGORY_NUMERIC, 0 }, { "DATE-TO-YYYYMMDD", -1, 1, CB_INTR_DATE_TO_YYYYMMDD, - "cob_intr_date_to_yyyymmdd", + "CobolIntrinsic.funcDateToYyyymmdd", CB_CATEGORY_NUMERIC, 0 }, { "DAY-OF-INTEGER", 1, 1, CB_INTR_DAY_OF_INTEGER, - "cob_intr_day_of_integer", + "CobolIntrinsic.funcDayOfInteger", CB_CATEGORY_NUMERIC, 0 }, { "DAY-TO-YYYYDDD", -1, 1, CB_INTR_DAY_TO_YYYYDDD, - "cob_intr_day_to_yyyyddd", + "CobolIntrinsic.funcDayToYyyyddd", CB_CATEGORY_NUMERIC, 0 }, { "DISPLAY-OF", -1, 0, CB_INTR_DISPLAY_OF, NULL, @@ -697,187 +697,187 @@ static const struct cb_intrinsic_table function_list[] = { NULL, CB_CATEGORY_NUMERIC, 0 }, { "EXCEPTION-FILE", 0, 1, CB_INTR_EXCEPTION_FILE, - "cob_intr_exception_file", + "CobolIntrinsic.funcExceptionFile", CB_CATEGORY_ALPHANUMERIC, 0 }, { "EXCEPTION-FILE-N", 0, 0, CB_INTR_EXCEPTION_FILE_N, NULL, CB_CATEGORY_ALPHANUMERIC, 0 }, { "EXCEPTION-LOCATION", 0, 1, CB_INTR_EXCEPTION_LOCATION, - "cob_intr_exception_location", + "CobolIntrinsic.funcExceptionLocation", CB_CATEGORY_ALPHANUMERIC, 0 }, { "EXCEPTION-LOCATION-N", 0, 0, CB_INTR_EXCEPTION_LOCATION_N, NULL, CB_CATEGORY_ALPHANUMERIC, 0 }, { "EXCEPTION-STATEMENT", 0, 1, CB_INTR_EXCEPTION_STATEMENT, - "cob_intr_exception_statement", + "CobolIntrinsic.funcExceptionStatement", CB_CATEGORY_ALPHANUMERIC, 0 }, { "EXCEPTION-STATUS", 0, 1, CB_INTR_EXCEPTION_STATUS, - "cob_intr_exception_status", + "CobolIntrinsic.funcExceptionStatus", CB_CATEGORY_ALPHANUMERIC, 0 }, { "EXP", 1, 1, CB_INTR_EXP, - "cob_intr_exp", + "CobolIntrinsic.funcExp", CB_CATEGORY_NUMERIC, 0 }, { "EXP10", 1, 1, CB_INTR_EXP10, - "cob_intr_exp10", + "CobolIntrinsic.funcExp10", CB_CATEGORY_NUMERIC, 0 }, { "FACTORIAL", 1, 1, CB_INTR_FACTORIAL, - "cob_intr_factorial", + "CobolIntrinsic.funcFactorial", CB_CATEGORY_NUMERIC, 0 }, { "FRACTION-PART", 1, 1, CB_INTR_FRACTION_PART, - "cob_intr_fraction_part", + "CobolIntrinsic.funcFractionPart", CB_CATEGORY_NUMERIC, 0 }, { "HIGHEST-ALGEBRAIC", 1, 0, CB_INTR_HIGHEST_ALGEBRAIC, NULL, CB_CATEGORY_NUMERIC, 0 }, { "INTEGER", 1, 1, CB_INTR_INTEGER, - "cob_intr_integer", + "CobolIntrinsic.funcInteger", CB_CATEGORY_NUMERIC, 0 }, { "INTEGER-OF-BOOLEAN", 1, 0, CB_INTR_INTEGER_OF_BOOLEAN, NULL, CB_CATEGORY_NUMERIC, 0 }, { "INTEGER-OF-DATE", 1, 1, CB_INTR_INTEGER_OF_DATE, - "cob_intr_integer_of_date", + "CobolIntrinsic.funcIntegerOfDate", CB_CATEGORY_NUMERIC, 0 }, { "INTEGER-OF-DAY", 1, 1, CB_INTR_INTEGER_OF_DAY, - "cob_intr_integer_of_day", + "CobolIntrinsic.funcIntegerOfDay", CB_CATEGORY_NUMERIC, 0 }, { "INTEGER-PART", 1, 1, CB_INTR_INTEGER_PART, - "cob_intr_integer_part", + "CobolIntrinsic.funcIntegerPart", CB_CATEGORY_NUMERIC, 0 }, { "LENG", 1, 1, CB_INTR_LENG, - "cob_intr_length", + "CobolIntrinsic.funcLength", CB_CATEGORY_NUMERIC, 0 }, { "LENGTH", 1, 1, CB_INTR_LENGTH, - "cob_intr_length", + "CobolIntrinsic.funcLength", CB_CATEGORY_NUMERIC, 0 }, { "LENGTH-AN", 1, 1, CB_INTR_LENGTH_AN, - "cob_intr_length", + "CobolIntrinsic.funcLength", CB_CATEGORY_NUMERIC, 0 }, { "LOCALE-COMPARE", -1, 0, CB_INTR_LOCALE_COMPARE, NULL, CB_CATEGORY_ALPHANUMERIC, 0 }, { "LOCALE-DATE", 2, 1, CB_INTR_LOCALE_DATE, - "cob_intr_locale_date", + "CobolIntrinsic.funcLocaleDate", CB_CATEGORY_ALPHANUMERIC, 1 }, { "LOCALE-TIME", 2, 1, CB_INTR_LOCALE_TIME, - "cob_intr_locale_time", + "CobolIntrinsic.funcLocaleTime", CB_CATEGORY_ALPHANUMERIC, 1 }, { "LOCALE-TIME-FROM-SECONDS", 2, 1, CB_INTR_LOCALE_TIME_FROM_SECS, - "cob_intr_lcl_time_from_secs", + "CobolIntrinsic.funcLclTimeFromSecs", CB_CATEGORY_ALPHANUMERIC, 1 }, { "LOG", 1, 1, CB_INTR_LOG, - "cob_intr_log", + "CobolIntrinsic.funcLog", CB_CATEGORY_NUMERIC, 0 }, { "LOG10", 1, 1, CB_INTR_LOG10, - "cob_intr_log10", + "CobolIntrinsic.funcLog10", CB_CATEGORY_NUMERIC, 0 }, { "LOWER-CASE", 1, 1, CB_INTR_LOWER_CASE, - "cob_intr_lower_case", + "CobolIntrinsic.funcLowerCase", CB_CATEGORY_ALPHANUMERIC, 1 }, { "LOWEST-ALGEBRAIC", 1, 0, CB_INTR_LOWEST_ALGEBRAIC, NULL, CB_CATEGORY_NUMERIC, 0 }, { "MAX", -1, 1, CB_INTR_MAX, - "cob_intr_max", + "CobolIntrinsic.funcMax", CB_CATEGORY_NUMERIC, 0 }, { "MEAN", -1, 1, CB_INTR_MEAN, - "cob_intr_mean", + "CobolIntrinsic.funcMean", CB_CATEGORY_NUMERIC, 0 }, { "MEDIAN", -1, 1, CB_INTR_MEDIAN, - "cob_intr_median", + "CobolIntrinsic.funcMedian", CB_CATEGORY_NUMERIC, 0 }, { "MIDRANGE", -1, 1, CB_INTR_MIDRANGE, - "cob_intr_midrange", + "CobolIntrinsic.funcMidrange", CB_CATEGORY_NUMERIC, 0 }, { "MIN", -1, 1, CB_INTR_MIN, - "cob_intr_min", + "CobolIntrinsic.funcMin", CB_CATEGORY_NUMERIC, 0 }, { "MOD", 2, 1, CB_INTR_MOD, - "cob_intr_mod", + "CobolIntrinsic.funcMod", CB_CATEGORY_NUMERIC, 0 }, { "NATIONAL", 1, 1, CB_INTR_NATIONAL, - "cob_intr_national", + "CobolIntrinsic.funcNational", CB_CATEGORY_NATIONAL, 0 }, { "NATIONAL-OF", -1, 0, CB_INTR_NATIONAL_OF, NULL, CB_CATEGORY_ALPHANUMERIC, 0 }, { "NUMVAL", 1, 1, CB_INTR_NUMVAL, - "cob_intr_numval", + "CobolIntrinsic.funcNumval", CB_CATEGORY_NUMERIC, 0 }, { "NUMVAL-C", 2, 1, CB_INTR_NUMVAL_C, - "cob_intr_numval_c", + "CobolIntrinsic.funcNumvalC", CB_CATEGORY_NUMERIC, 0 }, { "NUMVAL-F", 1, 0, CB_INTR_NUMVAL_F, NULL, CB_CATEGORY_NUMERIC, 0 }, { "ORD", 1, 1, CB_INTR_ORD, - "cob_intr_ord", + "CobolIntrinsic.funcOrd", CB_CATEGORY_NUMERIC, 0 }, { "ORD-MAX", -1, 1, CB_INTR_ORD_MAX, - "cob_intr_ord_max", + "CobolIntrinsic.funcOrdMax", CB_CATEGORY_NUMERIC, 0 }, { "ORD-MIN", -1, 1, CB_INTR_ORD_MIN, - "cob_intr_ord_min", + "CobolIntrinsic.funcOrdMin", CB_CATEGORY_NUMERIC, 0 }, { "PI", 0, 1, CB_INTR_PI, NULL, CB_CATEGORY_NUMERIC, 0 }, { "PRESENT-VALUE", -1, 1, CB_INTR_PRESENT_VALUE, - "cob_intr_present_value", + "CobolIntrinsic.funcPresentValue", CB_CATEGORY_NUMERIC, 0 }, { "RANDOM", -1, 1, CB_INTR_RANDOM, - "cob_intr_random", + "CobolIntrinsic.funcRandom", CB_CATEGORY_NUMERIC, 0 }, { "RANGE", -1, 1, CB_INTR_RANGE, - "cob_intr_range", + "CobolIntrinsic.funcRange", CB_CATEGORY_NUMERIC, 0 }, { "REM", 2, 1, CB_INTR_REM, - "cob_intr_rem", + "CobolIntrinsic.funcRem", CB_CATEGORY_NUMERIC, 0 }, { "REVERSE", 1, 1, CB_INTR_REVERSE, - "cob_intr_reverse", + "CobolIntrinsic.funcReverse", CB_CATEGORY_ALPHANUMERIC, 1 }, { "SECONDS-FROM-FORMATTED-TIME", 2, 1, CB_INTR_SECONDS_PAST_MIDNIGHT, - "cob_intr_seconds_from_formatted_time", + "CobolIntrinsic.funcSecondsFromFormattedTime", CB_CATEGORY_NUMERIC, 0 }, { "SECONDS-PAST-MIDNIGHT", 0, 1, CB_INTR_SECONDS_PAST_MIDNIGHT, - "cob_intr_seconds_past_midnight", + "CobolIntrinsic.funcSecondsPastMidnight", CB_CATEGORY_NUMERIC, 0 }, { "SIGN", 1, 1, CB_INTR_SIGN, - "cob_intr_sign", + "CobolIntrinsic.funcSign", CB_CATEGORY_NUMERIC, 0 }, { "SIN", 1, 1, CB_INTR_SIN, - "cob_intr_sin", + "CobolIntrinsic.funcSin", CB_CATEGORY_NUMERIC, 0 }, { "SQRT", 1, 1, CB_INTR_SQRT, - "cob_intr_sqrt", + "CobolIntrinsic.funcSqrt", CB_CATEGORY_NUMERIC, 0 }, { "STANDARD-COMPARE", -1, 0, CB_INTR_STANDARD_COMPARE, NULL, CB_CATEGORY_ALPHANUMERIC, 0 }, { "STANDARD-DEVIATION", -1, 1, CB_INTR_STANDARD_DEVIATION, - "cob_intr_standard_deviation", + "CobolIntrinsic.funcStandardDeviation", CB_CATEGORY_NUMERIC, 0 }, { "STORED-CHAR-LENGTH", 1, 1, CB_INTR_STORED_CHAR_LENGTH, - "cob_intr_stored_char_length", + "CobolIntrinsic.funcStoredCharLength", CB_CATEGORY_NUMERIC, 0 }, { "SUBSTITUTE", -1, 1, CB_INTR_SUBSTITUTE, - "cob_intr_substitute", + "CobolIntrinsic.funcSubstitute", CB_CATEGORY_ALPHANUMERIC, 1 }, { "SUBSTITUTE-CASE", -1, 1, CB_INTR_SUBSTITUTE_CASE, - "cob_intr_substitute_case", + "CobolIntrinsic.funcSubstituteCase", CB_CATEGORY_ALPHANUMERIC, 1 }, { "SUM", -1, 1, CB_INTR_SUM, - "cob_intr_sum", + "CobolIntrinsic.funcSum", CB_CATEGORY_NUMERIC, 0 }, { "TAN", 1, 1, CB_INTR_TAN, - "cob_intr_tan", + "CobolIntrinsic.funcTan", CB_CATEGORY_NUMERIC, 0 }, { "TEST-DATE-YYYYMMDD", 1, 1, CB_INTR_TEST_DATE_YYYYMMDD, - "cob_intr_test_date_yyyymmdd", + "CobolIntrinsic.funcTestDateYyyymmdd", CB_CATEGORY_NUMERIC, 0 }, { "TEST-DAY-YYYYDDD", 1, 1, CB_INTR_TEST_DAY_YYYYDDD, - "cob_intr_test_day_yyyyddd", + "CobolIntrinsic.funcTestDayYyyyddd", CB_CATEGORY_NUMERIC, 0 }, { "TEST-NUMVAL", 1, 0, CB_INTR_TEST_NUMVAL, NULL, @@ -889,19 +889,19 @@ static const struct cb_intrinsic_table function_list[] = { NULL, CB_CATEGORY_NUMERIC, 0 }, { "TRIM", 2, 1, CB_INTR_TRIM, - "cob_intr_trim", + "CobolIntrinsic.funcTrim", CB_CATEGORY_ALPHANUMERIC, 1 }, { "UPPER-CASE", 1, 1, CB_INTR_UPPER_CASE, - "cob_intr_upper_case", + "CobolIntrinsic.funcUpperCase", CB_CATEGORY_ALPHANUMERIC, 1 }, { "VARIANCE", -1, 1, CB_INTR_VARIANCE, - "cob_intr_variance", + "CobolIntrinsic.funcVariance", CB_CATEGORY_NUMERIC, 0 }, { "WHEN-COMPILED", 0, 1, CB_INTR_WHEN_COMPILED, - "cob_intr_when_compiled", + "CobolIntrinsic.funcWhenCompiled", CB_CATEGORY_ALPHANUMERIC, 1 }, { "YEAR-TO-YYYY", -1, 1, CB_INTR_YEAR_TO_YYYY, - "cob_intr_year_to_yyyy", + "CobolIntrinsic.funcYearToYyyy", CB_CATEGORY_NUMERIC, 0 } }; diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/common/CobolIntrinsic.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/common/CobolIntrinsic.java new file mode 100644 index 00000000..7e83815a --- /dev/null +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/common/CobolIntrinsic.java @@ -0,0 +1,1494 @@ +package jp.osscons.opensourcecobol.libcobj.common; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Random; + +import jp.osscons.opensourcecobol.libcobj.data.AbstractCobolField; +import jp.osscons.opensourcecobol.libcobj.data.CobolDataStorage; +import jp.osscons.opensourcecobol.libcobj.data.CobolDecimal; +import jp.osscons.opensourcecobol.libcobj.data.CobolFieldAttribute; +import jp.osscons.opensourcecobol.libcobj.data.CobolFieldFactory; +import jp.osscons.opensourcecobol.libcobj.exceptions.CobolExceptionId; +import jp.osscons.opensourcecobol.libcobj.exceptions.CobolRuntimeException; +import jp.osscons.opensourcecobol.libcobj.exceptions.CobolStopRunException; + +public class CobolIntrinsic { + + private static int[] normalDays = {0,31,59,90,120,151,181,212,243,273,304,334,365}; + private static int[] leapDays = {0,31,60,91,121,152,182,213,244,274,305,335,366}; + private static int[] normalMonthDays = {0,31,28,31,30,31,30,31,31,30,31,30,31}; + private static int[] leapMonthDays = {0,31,29,31,30,31,30,31,31,30,31,30,31}; + private final static int DEPTH_LEVEL = 8; + private final static int sizeOfDouble = 8; + private static int currEntry = 0; + private static AbstractCobolField currField = null; + private static CobolFieldAttribute currAttr = null; + private static AbstractCobolField[] calcField = new AbstractCobolField[DEPTH_LEVEL]; + private static CobolFieldAttribute[] calcAttr = new CobolFieldAttribute[DEPTH_LEVEL]; + private static Random random = new Random(); + + /** + * libcob/intrinsicのmake_double_entryの実装 + */ + private static void makeDoubleEntry() { + CobolDataStorage s = new CobolDataStorage(sizeOfDouble + 1); + + CobolFieldAttribute newAttr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_DOUBLE, + 18, + 9, + CobolFieldAttribute.COB_FLAG_HAVE_SIGN, + null); + AbstractCobolField newField = CobolFieldFactory.makeCobolField(sizeOfDouble, s, newAttr); + + calcAttr[currEntry] = newAttr; + calcField[currEntry] = newField; + currAttr = newAttr; + currField = newField; + if(++currEntry >= DEPTH_LEVEL) { + currEntry = 0; + } + } + + /** + * libcob/intrinsicのmake_field_entryの実装 + */ + private static void makeFieldEntry(AbstractCobolField f) { + AbstractCobolField newField = CobolFieldFactory.makeCobolField( + f.getSize(), new CobolDataStorage(f.getSize() + 1), f.getAttribute()); + calcField[currEntry] = newField; + calcAttr[currEntry] = f.getAttribute(); + currField = calcField[currEntry]; + currAttr = calcAttr[currEntry]; + + if(++currEntry >= DEPTH_LEVEL) { + currEntry = 0; + } + } + + /** + * libcob/intrinsicのcob_intr_ordの実装 + * @param year + * @return + */ + private static boolean isLeapYear(int year) { + return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)); + } + + /** + * libcob/intrinsicのcob_init_intrinsicの実装 + */ + public static void init() { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_ALPHANUMERIC, 0, 0, 0, null); + for(int i=0; i0; --n) v /= 10; + for(; n<0; ++n) v *= 10;*/ + for(int i=0; i 0) { + v /= 10; + } else { + v *= 10; + } + } + return v; + } + + /** + * libcob/intrinsicのcalc_ref_modの実装 + * @param f + * @param offset + * @param length + */ + private static void calcRefMod(AbstractCobolField f, int offset, int length) { + if(offset <= f.getSize()) { + int calcoff = offset - 1; + int size = f.getSize() - calcoff; + if(length > 0 && length < size) { + size = length; + } + f.setSize(size); + if(calcoff > 0) { + CobolDataStorage tmp = new CobolDataStorage(size); + tmp.memcpy(f.getDataStorage().getSubDataStorage(calcoff), size); + f.getDataStorage().memcpy(tmp, size); + } + } + } + + /** + * libcob/intrinsicのcob_intr_get_binopの実装 + * @param f1 + * @param op + * @param f2 + * @return + * @throws CobolStopRunException + */ + public static AbstractCobolField intrBinop(AbstractCobolField f1, int op, AbstractCobolField f2) throws CobolStopRunException { + CobolDecimal d1 = new CobolDecimal(); + CobolDecimal d2 = new CobolDecimal(); + d1.setField(f1); + d2.setField(f2); + + switch((char)op) { + case '+': d1.add(d2); break; + case '-': d1.sub(d2); break; + case '*': d1.mul(d2); break; + case '/': d1.div(d2); break; + case '^': d1.pow(d2); break; + default: break; + } + + int attrsign = 0; + int sign = 0; + if(d1.getValue().signum() < 0) { + attrsign = CobolFieldAttribute.COB_FLAG_HAVE_SIGN; + sign = 1; + } else { + attrsign = 0; + sign = 0; + } + + // BigDecimalに対するlog2を計算することをあきらめたため実装を変えた + int size = sizeInBase10(d1.getValue()); + if(d1.getScale() > size) { + size = d1.getScale(); + } + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_DISPLAY, size, d1.getScale(), attrsign, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(size, (CobolDataStorage)null, attr); + makeFieldEntry(field); + d1.getDisplayField(currField, 0); + return currField; + } + + /** + * libcob/intrinsicのcob_intr_lengthの実装 + * @param srcfield + * @return + */ + public static AbstractCobolField funcLength(AbstractCobolField srcfield) { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 8, 0, 0, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(4, (CobolDataStorage)null, attr); + makeFieldEntry(field); + currField.setInt(srcfield.getSize()); + return currField; + } + + /** + * libcob/intrinsicのcob_intr_integerの実装 + * @param srcfield + * @return + */ + public static AbstractCobolField funcInteger(AbstractCobolField srcfield) { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 18, 0, CobolFieldAttribute.COB_FLAG_HAVE_SIGN, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(8, (CobolDataStorage)null, attr); + makeFieldEntry(field); + + CobolDecimal d1 = new CobolDecimal(); + d1.setField(srcfield); + if(d1.getValue().signum() >= 0) { + try {d1.getField(currField, 0);} catch (CobolStopRunException e) {} + return currField; + } + + boolean isScalePositive = d1.getScale() > 0; + BigDecimal val = d1.getValue(); + for(int i=0; i 0) { + calcRefMod(currField, offset, length); + } + return currField; + } + + /** + * libcob/intrinsicのcob_intr_lower_caseの実装 + * @param srcfield + * @return + */ + public static AbstractCobolField funcLowerCase(int offset, int length, AbstractCobolField srcfield) { + makeFieldEntry(srcfield); + int size = srcfield.getSize(); + CobolDataStorage currStorage = currField.getDataStorage(); + CobolDataStorage srcStorage = srcfield.getDataStorage(); + for(int i=0; i 0) { + calcRefMod(currField, offset, length); + } + return currField; + } + + /** + * libcob/intrinsicのcob_intr_reverseの実装 + * @param srcfield + * @return + */ + public static AbstractCobolField funcReverse(int offset, int length, AbstractCobolField srcfield) { + makeFieldEntry(srcfield); + int size = srcfield.getSize(); + CobolDataStorage currStorage = currField.getDataStorage(); + CobolDataStorage srcStorage = srcfield.getDataStorage(); + for(int i=0; i 0) { + calcRefMod(currField, offset, length); + } + return currField; + } + + /** + * libcob/intrinsicのcob_intr_when_compiledの実装 + * @param offset + * @param length + * @param f + * @return + */ + public static AbstractCobolField funcWhenCompiled(int offset, int length, AbstractCobolField f) { + makeFieldEntry(f); + currField.getDataStorage().memcpy(f.getDataStorage(), f.getSize()); + if(offset > 0) { + calcRefMod(currField, offset, length); + } + return currField; + } + + /** + * libcob/intrinsicのcob_intr_current_dateの実装 + * @param offset + * @param length + * @return + */ + public static AbstractCobolField funcCurrentDate(int offset, int length) { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_ALPHANUMERIC, 0, 0, 0, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(21, (CobolDataStorage)null, attr); + makeFieldEntry(field); + Calendar cal = Calendar.getInstance(); + //TODO Time Zoneを表示する機能を取り入れる + String dateString = String.format("%4d%02d%02d%02d%02d%02d%02d00000", + cal.get(Calendar.YEAR), + cal.get(Calendar.MONTH), + cal.get(Calendar.DAY_OF_MONTH), + cal.get(Calendar.HOUR), + cal.get(Calendar.MINUTE), + cal.get(Calendar.SECOND), + cal.get(Calendar.MILLISECOND) / 10); + currField.getDataStorage().memcpy(dateString.getBytes()); + if(offset > 0) { + calcRefMod(currField, offset, length); + } + return currField; + } + + /** + * libcob/intrinsicのcob_intr_charの実装 + * @param srcfield + * @return + */ + public static AbstractCobolField funcChar(AbstractCobolField srcfield) { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_ALPHANUMERIC, 0, 0, 0, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(1, (CobolDataStorage)null, attr); + makeFieldEntry(field); + + int i = srcfield.getInt(); + if(i < 1 || i > 256) { + currField.getDataStorage().setByte(0, (byte)0); + } else { + currField.getDataStorage().setByte(0, (byte)(i - 1)); + } + return currField; + } + + /** + * libcob/intrinsicのcob_intr_ordの実装 + * @param srcfield + * @return + */ + public static AbstractCobolField funcOrd(AbstractCobolField srcfield) { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 8, 0, 0, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(4, (CobolDataStorage)null, attr); + makeFieldEntry(field); + + currField.setInt(srcfield.getDataStorage().getByte(0) + 1); + return currField; + } + + + /** + * libcob/intrinsicのcob_intr_date_of_integerの実装 + * @param srcdays + * @return + */ + public static AbstractCobolField funcDateOfInteger(AbstractCobolField srcdays) { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_DISPLAY, 8, 0, 0, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(8, (CobolDataStorage)null, attr); + makeFieldEntry(field); + + CobolRuntimeException.setException(0); + int days = srcdays.getInt(); + + if(days < 1 || days > 3067671) { + CobolRuntimeException.setException(CobolExceptionId.COB_EC_ARGUMENT_FUNCTION); + currField.getDataStorage().memset((byte)'0', 8); + return currField; + } + + int leapyear = 365; + int baseyear = 1601; + while(days > leapyear) { + days -= leapyear; + ++baseyear; + if(isLeapYear(baseyear)) { + leapyear = 366; + } else { + leapyear = 365; + } + } + int i; + for(i=0; i<13; ++i) { + if(isLeapYear(baseyear)) { + if(days <= leapDays[i]) { + days -= leapDays[i-1]; + break; + } + } else { + if(days <= normalDays[i]) { + days -= normalDays[i-1]; + break; + } + } + } + String dateString = String.format("%04d%02d%02d", baseyear, i , days); + currField.getDataStorage().memcpy(dateString.getBytes()); + return currField; + } + + /** + * libcob/intrinsicのcob_intr_day_of_integerの実装 + * @param srcdays + * @return + */ + public static AbstractCobolField funcDayOfInteger(AbstractCobolField srcdays) { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_DISPLAY, 7, 0, 0, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(7, (CobolDataStorage)null, attr); + makeFieldEntry(field); + + CobolRuntimeException.setException(0); + int days = srcdays.getInt(); + + if(days < 1 || days > 3067671) { + CobolRuntimeException.setException(CobolExceptionId.COB_EC_ARGUMENT_FUNCTION); + currField.getDataStorage().memset((byte)'0', 8); + return currField; + } + + int leapyear = 365; + int baseyear = 1601; + while(days > leapyear) { + days -= leapyear; + ++baseyear; + if(isLeapYear((baseyear))) { + leapyear = 366; + } else { + leapyear = 365; + } + } + String dateString = String.format("%04d%03d", baseyear, days); + currField.getDataStorage().memcpy(dateString.getBytes()); + return currField; + } + + /** + * libcob/intrinsicのcob_intr_integer_of_dateの実装 + * @param srcfield + * @return + */ + public static AbstractCobolField funcIntegerOfDate(AbstractCobolField srcfield) { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 8, 0, 0, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(4, (CobolDataStorage)null, attr); + makeFieldEntry(field); + + CobolRuntimeException.setException(0); + int indate = srcfield.getInt(); + int year = indate / 10000; + if(year < 1601 || year > 9999) { + CobolRuntimeException.setException(CobolExceptionId.COB_EC_ARGUMENT_FUNCTION); + currField.setInt(0); + return currField; + } + indate %= 10000; + int month = indate / 100; + if(month < 1 || month > 12) { + CobolRuntimeException.setException(CobolExceptionId.COB_EC_ARGUMENT_FUNCTION); + currField.setInt(0); + return currField; + } + int days = indate % 100; + if(days < 1 || days > 31) { + CobolRuntimeException.setException(CobolExceptionId.COB_EC_ARGUMENT_FUNCTION); + currField.setInt(0); + return currField; + } + if(isLeapYear(year)) { + if(days > leapMonthDays[month]) { + CobolRuntimeException.setException(CobolExceptionId.COB_EC_ARGUMENT_FUNCTION); + currField.setInt(0); + return currField; + } + } else { + if(days > normalMonthDays[month]) { + CobolRuntimeException.setException(CobolExceptionId.COB_EC_ARGUMENT_FUNCTION); + currField.setInt(0); + return currField; + } + } + + int totaldays = 0; + int baseyear = 1601; + while(baseyear != year) { + if(isLeapYear(baseyear)) { + totaldays += 366; + } else { + totaldays += 365; + } + ++baseyear; + } + + if(isLeapYear(baseyear)) { + totaldays += leapDays[month - 1]; + } else { + totaldays += normalDays[month - 1]; + } + + totaldays += days; + currField.setInt(totaldays); + return currField; + } + + /** + * libcob/intrinsicのcob_intr_integer_of_dayの実装 + * @param srcfield + * @return + */ + public static AbstractCobolField funcIntegerOfDay(AbstractCobolField srcfield) { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 8, 0, 0, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(4, (CobolDataStorage)null, attr); + makeFieldEntry(field); + + CobolRuntimeException.setException(0); + int indate = srcfield.getInt(); + int year = indate / 1000; + if(year < 1601 || year > 9999) { + CobolRuntimeException.setException(CobolExceptionId.COB_EC_ARGUMENT_FUNCTION); + currField.setInt(0); + return currField; + } + int days = indate % 1000; + if(days < 1 || days > 365 + (isLeapYear(year) ? 1 : 0)) { + CobolRuntimeException.setException(CobolExceptionId.COB_EC_ARGUMENT_FUNCTION); + currField.setInt(0); + return currField; + } + int totaldays = 0; + int baseyear = 1601; + while(baseyear != year) { + if(isLeapYear(baseyear)) { + totaldays += 366; + } else { + totaldays += 365; + } + ++baseyear; + } + totaldays += days; + currField.setInt(totaldays); + return currField; + } + + /** + * libcob/intrinsicのcob_intr_factorialの実装 + * @param srcfield + * @return + */ + public static AbstractCobolField funcFactorial(AbstractCobolField srcfield) { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 18, 0, 0, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(8, (CobolDataStorage)null, attr); + makeFieldEntry(field); + + CobolRuntimeException.setException(0); + int srcval = srcfield.getInt(); + if(srcval < 0) { + CobolRuntimeException.setException(CobolExceptionId.COB_EC_ARGUMENT_FUNCTION); + currField.setInt(0); + return currField; + } + BigDecimal d = new BigDecimal(1); + for(int i=2; i<=srcval; ++i){ + d = d.multiply(new BigDecimal(i)); + } + try { new CobolDecimal(d, 0).getField(currField, 0); } catch (CobolStopRunException e) {} + return currField; + } + + private static CobolDecimal mathFunctionBefore1(AbstractCobolField srcfield) { + CobolDecimal d1 = new CobolDecimal(); + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 18, 17, CobolFieldAttribute.COB_FLAG_HAVE_SIGN, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(8, (CobolDataStorage)null, attr); + d1.setField(srcfield); + makeFieldEntry(field); + return d1; + } + + private static CobolDecimal mathFunctionBefore2(AbstractCobolField srcfield) { + CobolDecimal d1 = new CobolDecimal(); + d1.setField(srcfield); + makeDoubleEntry(); + return d1; + } + + private static AbstractCobolField mathFunctionAfter1(double mathd2) { + if(Double.isNaN(mathd2) || mathd2 == Double.POSITIVE_INFINITY || mathd2 == Double.NEGATIVE_INFINITY) { + currField.setInt(0); + return currField; + } + long result = (long)mathd2; + mathd2 -= result; + for(int i=0; i<17; ++i) { + mathd2 *= 10; + int tempres = (int)mathd2; + result *= 10; + result += tempres; + mathd2 -= tempres; + } + currField.getDataStorage().set(result); + return currField; + } + + private static AbstractCobolField mathFunctionAfter2(double mathd2) { + if(Double.isNaN(mathd2) || mathd2 == Double.POSITIVE_INFINITY || mathd2 == Double.NEGATIVE_INFINITY) { + currField.setInt(0); + return currField; + } + currField.getDataStorage().set(mathd2); + return currField; + } + + /** + * libcob/intrinsicのcob_intr_expの実装 + */ + public static AbstractCobolField funcExp(AbstractCobolField srcfield) { + CobolDecimal d1 = mathFunctionBefore2(srcfield); + double mathd2 = Math.pow(2.7182818284590452354, intrGetDouble(d1)); + return mathFunctionAfter2(mathd2); + } + + /** + * libcob/intrinsicのcob_intr_exp10の実装 + */ + public static AbstractCobolField funcExp10(AbstractCobolField srcfield) { + CobolDecimal d1 = mathFunctionBefore2(srcfield); + double mathd2 = Math.pow(10, intrGetDouble(d1)); + return mathFunctionAfter2(mathd2); + } + + /** + * libcob/intrinsicのcob_intr_absの実装 + */ + public static AbstractCobolField funcAbs(AbstractCobolField srcfield) { + makeFieldEntry(srcfield); + CobolDecimal d1 = new CobolDecimal(); + d1.setValue(d1.getValue().abs()); + try { + d1.getField(currField, 0); + } catch (CobolStopRunException e) { + } + return currField; + } + + /** + * libcob/intrinsicのcob_intr_acosの実装 + */ + public static AbstractCobolField funcAcos(AbstractCobolField srcfield) { + CobolDecimal d1 = mathFunctionBefore1(srcfield); + double mathd2 = Math.acos(intrGetDouble(d1)); + return mathFunctionAfter1(mathd2); + } + + /** + * libcob/intrinsicのcob_intr_asinの実装 + */ + public static AbstractCobolField funcAsin(AbstractCobolField srcfield) { + CobolDecimal d1 = mathFunctionBefore1(srcfield); + double mathd2 = Math.asin(intrGetDouble(d1)); + return mathFunctionAfter1(mathd2); + } + + /** + * libcob/intrinsicのcob_intr_atanの実装 + */ + public static AbstractCobolField funcAtan(AbstractCobolField srcfield) { + CobolDecimal d1 = mathFunctionBefore1(srcfield); + double mathd2 = Math.atan(intrGetDouble(d1)); + return mathFunctionAfter1(mathd2); + } + + /** + * libcob/intrinsicのcob_intr_cosの実装 + */ + public static AbstractCobolField funcCos(AbstractCobolField srcfield) { + CobolDecimal d1 = mathFunctionBefore1(srcfield); + double mathd2 = Math.cos(intrGetDouble(d1)); + return mathFunctionAfter1(mathd2); + } + + /** + * libcob/intrinsicのcob_intr_logの実装 + */ + public static AbstractCobolField funcLog(AbstractCobolField srcfield) { + CobolDecimal d1 = mathFunctionBefore2(srcfield); + double mathd2 = Math.log(intrGetDouble(d1)); + return mathFunctionAfter2(mathd2); + } + + /** + * libcob/intrinsicのcob_intr_log10の実装 + */ + public static AbstractCobolField funcLog10(AbstractCobolField srcfield) { + CobolDecimal d1 = mathFunctionBefore2(srcfield); + double mathd2 = Math.log10(intrGetDouble(d1)); + return mathFunctionAfter2(mathd2); + } + + /** + * libcob/intrinsicのcob_intr_sinの実装 + */ + public static AbstractCobolField funcSin(AbstractCobolField srcfield) { + CobolDecimal d1 = mathFunctionBefore1(srcfield); + double mathd2 = Math.sin(intrGetDouble(d1)); + return mathFunctionAfter1(mathd2); + } + + /** + * libcob/intrinsicのcob_intr_sqrtの実装 + */ + public static AbstractCobolField funcSqrt(AbstractCobolField srcfield) { + CobolDecimal d1 = mathFunctionBefore2(srcfield); + double mathd2 = Math.sqrt(intrGetDouble(d1)); + return mathFunctionAfter2(mathd2); + } + + /** + * libcob/intrinsicのcob_intr_tanの実装 + */ + public static AbstractCobolField funcTan(AbstractCobolField srcfield) { + CobolDecimal d1 = mathFunctionBefore2(srcfield); + double mathd2 = Math.tan(intrGetDouble(d1)); + return mathFunctionAfter2(mathd2); + } + + /** + * libcob/intrinsicのcob_intr_numvalの実装 + * @param srcfield + * @return + */ + public static AbstractCobolField funcNumval(AbstractCobolField srcfield) { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 18, 0, CobolFieldAttribute.COB_FLAG_HAVE_SIGN, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(8, (CobolDataStorage)null, attr); + + CobolDataStorage s = srcfield.getDataStorage(); + boolean sign = false; + boolean decimalSeen = false; + long llval = 0; + int integerDigits = 0; + int decimalDigits = 0; + StringBuilder integerBuff = new StringBuilder(); + StringBuilder decimalBuff = new StringBuilder(); + for(int i=0; i= '0' && c <= '9') { + llval *= 10; + llval += c - '0'; + if(decimalSeen) { + decimalBuff.append(c); + decimalDigits++; + } else { + integerBuff.append(c); + integerDigits++; + } + } + if(integerDigits + decimalDigits > 30) { + break; + } + } + if(integerDigits > 0) { + integerBuff.setCharAt(0, '0'); + } + if(decimalDigits > 0) { + decimalBuff.setCharAt(0, '0'); + } + if(sign) { + llval = -llval; + } + if(integerDigits + decimalDigits <= 18) { + attr.setScale(decimalDigits); + makeFieldEntry(field); + currField.getDataStorage().set(llval); + } else { + String dataString = String.format("%s%s.%s", sign ? "-" : "", integerBuff.toString(), decimalBuff.toString()); + double val = Double.parseDouble(dataString); + makeDoubleEntry(); + currField.getDataStorage().set(val); + } + return currField; + } + /** + * libcob/intrinsicのcob_intr_numval_cの実装 + * @param srcfield + * @return + */ + public static AbstractCobolField funcNumvalC(AbstractCobolField srcfield, AbstractCobolField currency) { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 18, 0, CobolFieldAttribute.COB_FLAG_HAVE_SIGN, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(8, (CobolDataStorage)null, attr); + + CobolDataStorage s = srcfield.getDataStorage(); + boolean sign = false; + boolean decimalSeen = false; + long llval = 0; + int integerDigits = 0; + int decimalDigits = 0; + StringBuilder integerBuff = new StringBuilder(); + StringBuilder decimalBuff = new StringBuilder(); + + CobolDataStorage currencyData = null; + if(currency != null) { + if(currency.getSize() < srcfield.getSize()) { + currencyData = currency.getDataStorage(); + } + } + for(int i=0; i= '0' && c <= '9') { + llval *= 10; + llval += c - '0'; + if(decimalSeen) { + decimalBuff.append(c); + decimalDigits++; + } else { + integerBuff.append(c); + integerDigits++; + } + } + if(integerDigits + decimalDigits > 30) { + break; + } + } + if(integerDigits > 0) { + integerBuff.setCharAt(0, '0'); + } + if(decimalDigits > 0) { + decimalBuff.setCharAt(0, '0'); + } + if(sign) { + llval = -llval; + } + if(integerDigits + decimalDigits <= 18) { + attr.setScale(decimalDigits); + makeFieldEntry(field); + currField.getDataStorage().set(llval); + } else { + String dataString = String.format("%s%s.%s", sign ? "-" : "", integerBuff.toString(), decimalBuff.toString()); + double val = Double.parseDouble(dataString); + makeDoubleEntry(); + currField.getDataStorage().set(val); + } + return currField; + } + + public static AbstractCobolField funcNumvalC(int n, AbstractCobolField currency) { + return funcNumvalC(null, currency); + } + public static AbstractCobolField funcNumvalC(AbstractCobolField srcfield, int n) { + return funcNumvalC(srcfield, null); + } + public static AbstractCobolField funcNumvalC(int n, int m) { + return funcNumvalC(null, null); + } + + /** + * libcob/intrinsicのcob_intr_annuityの実装 + * @param srcfield1 + * @param srcfield2 + * @return + */ + public static AbstractCobolField funcAnnuity(AbstractCobolField srcfield1, AbstractCobolField srcfield2) { + makeDoubleEntry(); + CobolDecimal d1 = new CobolDecimal(); + CobolDecimal d2 = new CobolDecimal(); + d1.setField(srcfield1); + d2.setField(srcfield2); + + double mathd1 = intrGetDouble(d1); + double mathd2 = intrGetDouble(d2); + if(mathd1 == 0) { + mathd1 = 1.0 / mathd2; + currField.getDataStorage().set(mathd1); + return currField; + } + + mathd1 /= (1.0 - Math.pow(mathd1 + 1.0, 0.0 - mathd2)); + currField.getDataStorage().set(mathd1); + return currField; + } + + private static int sizeInBase10(BigDecimal d1) { + String s = d1.toPlainString(); + int begin = s.charAt(0) == '-' ? 0 : -1; + int pointIndex = s.indexOf('.'); + int end = pointIndex < 0 ? s.length() : pointIndex; + return end - begin -1; + } + + /** + * libcob/intrinsicのcob_intr_sumの実装 + * @param params + * @param fields + * @return + */ + public static AbstractCobolField funcSum(int params, AbstractCobolField... fields) { + CobolDecimal d1 = new CobolDecimal(); + CobolDecimal d2 = new CobolDecimal(); + d1.setValue(BigDecimal.ZERO); + + int scale = 0; + for(AbstractCobolField f: fields) { + if(f.getAttribute().getScale() > scale) { + scale = f.getAttribute().getScale(); + } + d2.setField(f); + d1.add(d2); + } + + int size = sizeInBase10(d1.getValue()); + AbstractCobolField field; + if(size < 19) { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 18, scale, CobolFieldAttribute.COB_FLAG_HAVE_SIGN, null); + field = CobolFieldFactory.makeCobolField(8, (CobolDataStorage)null, attr); + } else { + if(d1.getScale() > size) { + size = d1.getScale(); + } + if(scale > size) { + size = scale; + } + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_DISPLAY, size, scale, CobolFieldAttribute.COB_FLAG_HAVE_SIGN, null); + field = CobolFieldFactory.makeCobolField(size, (CobolDataStorage)null, attr); + } + makeFieldEntry(field); + try { + d1.getField(currField, 0); + } catch(CobolStopRunException e) { + } + return currField; + } + + /** + * libcob/intrinsicのcob_intr_ord_minの実装 + * @param params + * @param fields + * @return + */ + public static AbstractCobolField funcOrdMin(int params, AbstractCobolField... fields) { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_DISPLAY, 8, 0, 0, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(4, (CobolDataStorage)null, attr); + makeFieldEntry(field); + + if(fields.length <= 1) { + currField.setInt(0); + return currField; + } + + AbstractCobolField basef = fields[0]; + int ordmin = 0; + for(int i=1; i 0) { + basef = f; + ordmax = i; + } + } + + currField.setInt(ordmax + 1); + return currField; + } + + /** + * libcob/intrinsicのcob_intr_minの実装 + * @param params + * @param fields + * @return + */ + public static AbstractCobolField funcMin(int params, AbstractCobolField... fields) { + AbstractCobolField beasef = fields[0]; + for(int i=1; i 0) { + beasef = f; + } + } + + return beasef; + } + + /** + * libcob/intrinsicのcob_intr_midrangeの実装 + * @param params + * @param fields + * @return + */ + public static AbstractCobolField funcMidrange(int params, AbstractCobolField... fields) { + makeDoubleEntry(); + AbstractCobolField basemin = fields[0]; + AbstractCobolField basemax = fields[0]; + for(int i=1; i 0) { + basemax = f; + } + } + + CobolDecimal d1 = new CobolDecimal(); + CobolDecimal d2 = new CobolDecimal(); + d1.setField(basemin); + d2.setField(basemax); + d1.add(d2); + d2 = new CobolDecimal(new BigDecimal(2), 0); + try { + d1.div(d2); + d1.getField(currField, 0); + } catch (CobolStopRunException e) { + } + return currField; + } + + /** + * libcob/intrinsicのcob_intr_medianの実装 + * @param params + * @param fields + * @return + */ + public static AbstractCobolField funcMedian(int params, AbstractCobolField... fields) { + if(fields.length == 1) { + return fields[0]; + } + + AbstractCobolField[] fieldAlloc = new AbstractCobolField[fields.length]; + + for(int i=0; i a.compareTo(b)); + int i = params / 2; + if(params % 2 != 0) { + return fieldAlloc[i]; + } else { + makeDoubleEntry(); + CobolDecimal d1 = new CobolDecimal(); + CobolDecimal d2 = new CobolDecimal(); + d1.setField(fieldAlloc[i]); + d2.setField(fieldAlloc[i-1]); + d1.add(d2); + d2 = new CobolDecimal(new BigDecimal(2), 0); + try { + d1.div(d2); + d1.getField(currField, 0); + } catch (CobolStopRunException e) { + } + return currField; + } + } + + /** + * libcob/intrinsicのcob_intr_medianの実装 + * @param pramas + * @param fields + * @return + */ + public static AbstractCobolField funcMean(int pramas, AbstractCobolField... fields) { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 18, 0, CobolFieldAttribute.COB_FLAG_HAVE_SIGN, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(8, (CobolDataStorage)null, attr); + CobolDecimal d1 = new CobolDecimal(BigDecimal.ZERO); + CobolDecimal d2 = new CobolDecimal(); + + for(AbstractCobolField f: fields) { + d2.setField(f); + d1.add(d2); + } + + d2 = new CobolDecimal(new BigDecimal(fields.length), 0); + try { d1.div(d2); } catch (CobolStopRunException e) {} + + CobolDataStorage storage = new CobolDataStorage(8); + field.setDataStorage(storage); + try { d1.getField(field, 0); } catch (CobolStopRunException e) {} + long n = storage.longValue(); + int i; + for(i=0; n!=0; n /= 10, ++i); + field.setDataStorage(null); + if(i <= 18) { + attr.setScale(18 - i); + } + makeFieldEntry(field); + try{ d1.getField(currField, 0); } catch (CobolStopRunException e) {} + return currField; + } + + /** + * libcob/intrinsicのcob_intr_modの実装 + * @param srcfield1 + * @param srcfield2 + * @return + * @throws CobolStopRunException + */ + public static AbstractCobolField funcMod(AbstractCobolField srcfield1, AbstractCobolField srcfield2) throws CobolStopRunException { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 18, 0, CobolFieldAttribute.COB_FLAG_HAVE_SIGN, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(8, (CobolDataStorage)null, attr); + CobolDecimal d1 = new CobolDecimal(); + CobolDecimal d2 = new CobolDecimal(); + makeFieldEntry(field); + + AbstractCobolField f1 = funcInteger(intrBinop(srcfield1, '/', srcfield2)); + d1.setField(srcfield2); + d2.setField(f1); + d2.mul(d1); + d1.setField(srcfield1); + d1.sub(d2); + try { d1.getField(currField, 0); } catch (CobolStopRunException e) {} + return currField; + } + + /** + * libcob/intrinsicのcob_intr_rangeの実装 + * @param params + * @param fields + * @return + * @throws CobolStopRunException + */ + public static AbstractCobolField funcRange(int params, AbstractCobolField... fields) throws CobolStopRunException { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 18, 0, CobolFieldAttribute.COB_FLAG_HAVE_SIGN, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(8, (CobolDataStorage)null, attr); + CobolDecimal d1 = new CobolDecimal(); + CobolDecimal d2 = new CobolDecimal(); + + AbstractCobolField basemin = fields[0]; + AbstractCobolField basemax = fields[0]; + for(int i=1; i 0) { + basemax = f; + } + } + + attr.setScale(basemin.getAttribute().getScale()); + if(basemax.getAttribute().getScale() > attr.getScale()) { + attr.setScale(basemax.getAttribute().getScale()); + } + makeFieldEntry(field); + d1.setField(basemax); + d2.setField(basemin); + d1.sub(d2); + d1.getField(currField, 0); + return currField; + } + + /** + * libcob/intrinsicのcob_intr_remの実装 + * @param srcfield1 + * @param srcfield2 + * @return + * @throws CobolStopRunException + */ + public static AbstractCobolField funcRem(AbstractCobolField srcfield1, AbstractCobolField srcfield2) throws CobolStopRunException { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 18, 0, CobolFieldAttribute.COB_FLAG_HAVE_SIGN, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(8, (CobolDataStorage)null, attr); + AbstractCobolField f1 = funcIntegerPart(intrBinop(srcfield1, '/', srcfield2)); + CobolDecimal d1 = new CobolDecimal(); + CobolDecimal d2 = new CobolDecimal(); + + d1.setField(srcfield2); + d2.setField(f1); + d2.mul(d1); + d1.setField(srcfield1); + d1.sub(d2); + + attr.setScale(srcfield1.getAttribute().getScale()); + if(srcfield2.getAttribute().getScale() > attr.getScale()) { + attr.setScale(srcfield2.getAttribute().getScale()); + } + makeFieldEntry(field); + d1.getField(currField, 0); + return currField; + } + + /** + * libcob/intrinsicのcob_intr_randomの実装 + * @param prams + * @param fields + * @return + */ + public static AbstractCobolField funcRandom(int prams, AbstractCobolField... fields) { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 18, 0, CobolFieldAttribute.COB_FLAG_HAVE_SIGN, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(8, (CobolDataStorage)null, attr); + + if(fields.length > 0) { + AbstractCobolField f = fields[0]; + int seed = f.getInt(); + if(seed < 0) { + seed = 0; + } + random.setSeed(seed); + } + + int r = random.nextInt(1000000001); + + int exp10 = 1; + int i=0; + for(i=0; i<10; ++i) { + if(r / exp10 == 0) { + break; + } + exp10 *= 10; + } + if(i == 0) { + i = 1; + } + attr.setScale(i); + makeFieldEntry(field); + currField.getDataStorage().set((long)r); + return currField; + } + + /** + * libcob/intrinsicのcob_intr_varianceの実装 + * @param prams + * @param fields + * @return + * @throws CobolStopRunException + */ + public static AbstractCobolField funcVariance(int prams, AbstractCobolField... fields) throws CobolStopRunException { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 18, 0, CobolFieldAttribute.COB_FLAG_HAVE_SIGN, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(8, (CobolDataStorage)null, attr); + + if(fields.length == 1) { + makeFieldEntry(field); + currField.setInt(0); + return currField; + } + + CobolDecimal d1 = new CobolDecimal(new BigDecimal(0), 0); + CobolDecimal d2 = new CobolDecimal(); + + for(AbstractCobolField f: fields) { + d2.setField(f); + d1.add(d2); + } + + d2.setValue(new BigDecimal(fields.length)); + d2.setScale(0); + try { d1.div(d2); } catch (CobolStopRunException e) {} + + CobolDecimal d4 = new CobolDecimal(new BigDecimal(0), 0); + + for(AbstractCobolField f: fields) { + d2.setField(f); + d2.sub(d1); + d2.mul(d2); + d4.add(d2); + } + + CobolDecimal d3 = new CobolDecimal(new BigDecimal(fields.length), 0); + try { d4.div(d3); } catch (CobolStopRunException e) {} + CobolDataStorage data = new CobolDataStorage(8); + field.setDataStorage(data); + d4.getDisplayField(field, 0); + long n = data.longValue(); + int i=0; + for(i=0; n!=0; n /=10, ++i); + field.setDataStorage(null); + if(i <= 18) { + attr.setScale(18 - i); + } + makeDoubleEntry(); + d4.getField(currField, 0); + return currField; + } + + /** + * libcob/intrinsicのcob_intr_standard_deviationの実装 + * @param prams + * @param fields + * @return + * @throws CobolStopRunException + */ + public static AbstractCobolField funcStandardDeviation(int prams, AbstractCobolField... fields) throws CobolStopRunException { + CobolFieldAttribute attr = new CobolFieldAttribute( + CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY, 18, 0, CobolFieldAttribute.COB_FLAG_HAVE_SIGN, null); + AbstractCobolField field = CobolFieldFactory.makeCobolField(8, (CobolDataStorage)null, attr); + + makeDoubleEntry(); + + if(fields.length == 1) { + makeFieldEntry(field); + currField.setInt(0); + return currField; + } + + CobolDecimal d1 = new CobolDecimal(new BigDecimal(0), 0); + CobolDecimal d2 = new CobolDecimal(); + + for(AbstractCobolField f: fields) { + d2.setField(f); + d1.add(d2); + } + + d2.setValue(new BigDecimal(fields.length)); + d2.setScale(0); + try { d1.div(d2); } catch (CobolStopRunException e) {} + + CobolDecimal d4 = new CobolDecimal(new BigDecimal(0), 0); + + for(AbstractCobolField f: fields) { + d2.setField(f); + d2.sub(d1); + d2.mul(d2); + d4.add(d2); + } + + CobolDecimal d3 = new CobolDecimal(new BigDecimal(fields.length), 0); + try { d4.div(d3); } catch (CobolStopRunException e) {} + d4.getField(currField, 0); + return funcSqrt(currField); + } + + /** + * libcob/intrinsicのcob_intr_present_valueの実装 + * @param prams + * @param fields + * @return + * @throws CobolStopRunException + */ + public static AbstractCobolField funcPresentValue(int prams, AbstractCobolField... fields) throws CobolStopRunException { + makeDoubleEntry(); + if(fields.length < 2) { + System.err.println("Wrong number of parameters for FUNCTION PRESENT-VALUE"); + System.err.flush(); + currField.setInt(0); + return currField; + } + AbstractCobolField f = fields[0]; + CobolDecimal d1 = new CobolDecimal(); + d1.setField(f); + CobolDecimal d2 = new CobolDecimal(new BigDecimal(1), 0); + d1.add(d2); + CobolDecimal d4 = new CobolDecimal(new BigDecimal(0), 0); + + for(int i=1; i 1) { + CobolDecimal d5 = new CobolDecimal(new BigDecimal(i), 0); + d3.pow(d5); + } + d2.div(d3); + d4.add(d2); + } + + d4.getField(currField, 0); + return currField; + } +} diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/common/CobolUtil.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/common/CobolUtil.java index d46ddea3..51a00c6f 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/common/CobolUtil.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/common/CobolUtil.java @@ -103,6 +103,7 @@ public static void cob_init(String[] argv, boolean cob_initialized) { CobolUtil.commandLineArgs = argv; CobolInspect.initString(); CobolFile.cob_init_fileio(); + CobolIntrinsic.init(); for(int i=0; i<8; ++i) { String envVariableName = String.format("COB_SWITCH_%d", i + 1); diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/AbstractCobolField.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/AbstractCobolField.java index 8353e3e8..39b50c09 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/AbstractCobolField.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/AbstractCobolField.java @@ -89,14 +89,21 @@ public AbstractCobolField (int size, CobolDataStorage dataStorage, CobolFieldAtt public CobolDataStorage getDataStorage() { return dataStorage; } + /** * メンバ変数dataStorageのsetter - * @return this.dataStorage */ public void setDataStorage(CobolDataStorage dataStorage) { this.dataStorage = dataStorage; } + /** + * メンバ変数attirbuteのsetter + */ + public void setAttribute(CobolFieldAttribute attribute) { + this.attribute = attribute; + } + /** * メンバ変数attributeのgetter * @return this.attribute diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolAlphanumericField.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolAlphanumericField.java index afe82690..f0607396 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolAlphanumericField.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolAlphanumericField.java @@ -95,6 +95,8 @@ public void moveFrom(AbstractCobolField src) { return; case CobolFieldAttribute.COB_TYPE_NUMERIC_PACKED: case CobolFieldAttribute.COB_TYPE_NUMERIC_BINARY: + case CobolFieldAttribute.COB_TYPE_NUMERIC_DOUBLE: + case CobolFieldAttribute.COB_TYPE_NUMERIC_FLOAT: this.moveFrom(src1.getNumericField()); return; case CobolFieldAttribute.COB_TYPE_ALPHANUMERIC: diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolDataStorage.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolDataStorage.java index ff49f26b..32f48c2c 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolDataStorage.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolDataStorage.java @@ -461,13 +461,21 @@ public void set(int value) { } /** - * this.dataにlong型のvalueを4バイトで書き込む + * this.dataにlong型のvalueを8バイトで書き込む * @param value this.dataに書き込むlong型の値 */ public void set(long value) { ByteBuffer.wrap(this.data, this.index, 8).putLong(value); } + /** + * this.dataにdouble型のvalueを4バイトで書き込む + * @param value this.dataに書き込むlong型の値 + */ + public void set(double value) { + ByteBuffer.wrap(this.data, this.index, 8).putDouble(value); + } + public void set(CobolDataStorage other) { this.set(other.intValue()); } @@ -509,6 +517,10 @@ public int intValue() { public long longValue() { return ByteBuffer.wrap(this.data, this.index, Long.BYTES).getLong(); } + + public double doubleValue() { + return ByteBuffer.wrap(this.data, this.index, Double.BYTES).getDouble(); + } /** * メンバ変数indexの値がthis.index+indexであるようなCobolDataStorageのインスタンスを返す diff --git a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolDecimal.java b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolDecimal.java index f0a6f9f9..d696405b 100644 --- a/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolDecimal.java +++ b/libcobj/src/jp/osscons/opensourcecobol/libcobj/data/CobolDecimal.java @@ -452,7 +452,7 @@ public int getField(AbstractCobolField f, int opt) throws CobolStopRunException CobolDecimal d = new CobolDecimal(this); /* rounding */ - if((opt & CobolDecimal.COB_STORE_ROUND) > 0) { + if((opt & CobolDecimal.COB_STORE_ROUND) != 0) { if(f.getAttribute().getScale() < d.getScale()) { int sign = d.value.signum(); if(sign != 0) { @@ -480,8 +480,7 @@ public int getField(AbstractCobolField f, int opt) throws CobolStopRunException System.out.println("getField: Float not implemented"); throw new CobolRuntimeException(0, "getField: Float not implemented"); case CobolFieldAttribute.COB_TYPE_NUMERIC_DOUBLE: - System.out.println("getField: Double not implemented"); - throw new CobolRuntimeException(0, "getField: Double not implemented"); + return d.getDoubleField(f, opt); default: int digits = f.getAttribute().getDigits(); CobolFieldAttribute attr = f.getAttribute(); @@ -498,6 +497,23 @@ public int getField(AbstractCobolField f, int opt) throws CobolStopRunException return CobolException.code; } } + + public int getDoubleField(AbstractCobolField f, int opt) { + CobolDataStorage storage = new CobolDataStorage(8); + double val = this.value.doubleValue(); + int scale = this.scale; + for(int i=0; i 0) { + val /= 10; + } else { + val *= 10; + } + } + storage.set(val); + f.setDataStorage(storage); + return 0; + + } /** * libcob/numeric.c shift_decimalの実装 @@ -551,7 +567,8 @@ public int compareTo(CobolDecimal decimal) { public int getDisplayField(AbstractCobolField f, int opt) throws CobolStopRunException { int sign = this.value.signum(); this.value = this.value.abs(); - byte[] numBuffPtr = this.value.toPlainString().getBytes(); + String numString = this.value.toPlainString(); + byte[] numBuffPtr = numString.getBytes(); int size = numBuffPtr.length; CobolDataStorage data = f.getDataStorage(); @@ -562,8 +579,27 @@ public int getDisplayField(AbstractCobolField f, int opt) throws CobolStopRunExc if((opt & CobolDecimal.COB_STORE_KEEP_ON_OVERFLOW) > 0) { return CobolRuntimeException.code; } + + //TODO else でもこのような処理に書き変えなくていいのか考える + BigDecimal val = this.value; + for(int i=0; i= 0 ? 1 : -1); + } + private void moveEditedToDisplay(AbstractCobolField field) { byte[] buff = new byte[64]; int p = 0; diff --git a/tests/cobol85/report.pl b/tests/cobol85/report.pl index ff108c1c..9c8a5910 100644 --- a/tests/cobol85/report.pl +++ b/tests/cobol85/report.pl @@ -68,46 +68,47 @@ $skip{OBNC2M} = 1; -#$skip{IX101A}=1; -#$skip{IX102A}=1; -#$skip{IX103A}=1; -#$skip{IX104A}=1; -#$skip{IX105A}=1; -#$skip{IX106A}=1; -#$skip{IX107A}=1; -#$skip{IX108A}=1; -#$skip{IX109A}=1; -#$skip{IX110A}=1; -#$skip{IX111A}=1; -#$skip{IX112A}=1; -#$skip{IX113A}=1; -#$skip{IX114A}=1; -#$skip{IX115A}=1; -#$skip{IX116A}=1; -#$skip{IX117A}=1; -#$skip{IX118A}=1; -#$skip{IX119A}=1; -#$skip{IX120A}=1; -#$skip{IX121A}=1; -#$skip{IX201A}=1; -#$skip{IX202A}=1; -#$skip{IX203A}=1; -#$skip{IX204A}=1; -#$skip{IX205A}=1; -#$skip{IX206A}=1; -#$skip{IX207A}=1; -#$skip{IX208A}=1; -#$skip{IX209A}=1; -#$skip{IX210A}=1; -#$skip{IX211A}=1; -#$skip{IX212A}=1; -#$skip{IX213A}=1; -#$skip{IX214A}=1; -#$skip{IX215A}=1; -#$skip{IX216A}=1; +$skip{IX101A}=1; +$skip{IX102A}=1; +$skip{IX103A}=1; +$skip{IX104A}=1; +$skip{IX105A}=1; +$skip{IX106A}=1; +$skip{IX107A}=1; +$skip{IX108A}=1; +$skip{IX109A}=1; +$skip{IX110A}=1; +$skip{IX111A}=1; +$skip{IX112A}=1; +$skip{IX113A}=1; +$skip{IX114A}=1; +$skip{IX115A}=1; +$skip{IX116A}=1; +$skip{IX117A}=1; +$skip{IX118A}=1; +$skip{IX119A}=1; +$skip{IX120A}=1; +$skip{IX121A}=1; +$skip{IX201A}=1; +$skip{IX202A}=1; +$skip{IX203A}=1; +$skip{IX204A}=1; +$skip{IX205A}=1; +$skip{IX206A}=1; +$skip{IX207A}=1; +$skip{IX208A}=1; +$skip{IX209A}=1; +$skip{IX210A}=1; +$skip{IX211A}=1; +$skip{IX212A}=1; +$skip{IX213A}=1; +$skip{IX214A}=1; +$skip{IX215A}=1; +$skip{IX216A}=1; #$skip{IX217A}=1; #$skip{IX218A}=1; + open (LOG, "> report.txt") or die; print LOG "Filename total pass fail deleted inspect\n"; print LOG "-------- ----- ---- ---- ------- -------\n"; From a82e2a0431cb1e8184529455468b44cc62667b98 Mon Sep 17 00:00:00 2001 From: Yutaro Sakamoto Date: Fri, 25 Jun 2021 04:59:56 +0000 Subject: [PATCH 4/4] =?UTF-8?q?README=E3=81=ABFUNCTION=E3=82=92=E5=AE=9F?= =?UTF-8?q?=E8=A3=85=E3=81=97=E3=81=9F=E3=81=93=E3=81=A8=E3=82=92=E8=A8=98?= =?UTF-8?q?=E8=BC=89=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- README_JP.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a593217b..9ef93ea6 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ java [PROGRAM-ID] ## The progress of the development The functions in the following "implemented" list are tested using [NIST COBOL85 test suite](https://www.itl.nist.gov/div897/ctg/cobol_form.htm) -and **95%** of the test cases are passed. +and **96%** of the test cases are passed. Implemented. @@ -39,11 +39,11 @@ Implemented. * Sequential files * Indexed files * Sort statements +* Embedded functions (ACOS, LENGTH, MAX, ...) Not Implemented. * Relative files -* Embedded functions (ACOS, LENGTH, MAX, ...) Known bugs diff --git a/README_JP.md b/README_JP.md index 8150577e..155ee425 100644 --- a/README_JP.md +++ b/README_JP.md @@ -26,7 +26,7 @@ java [PROGRAM-ID] ## The progress of the development -下記の実装済みリストにある機能は[NIST COBOL85 test suite](https://www.itl.nist.gov/div897/ctg/cobol_form.htm)でテストされており,**95%** のテストケースをパスしています. +下記の実装済みリストにある機能は[NIST COBOL85 test suite](https://www.itl.nist.gov/div897/ctg/cobol_form.htm)でテストされており,**96%** のテストケースをパスしています. 実装済み @@ -37,11 +37,11 @@ java [PROGRAM-ID] * SEQUENTIALファイルの入出力機能 * INDEXEDファイルの入出力機能 * SORT文 +* 組み込み関数 (ACOS, LENGTH, MAX, ...) 実装予定 * RELATIVEファイルの入出力機能 -* 組み込み関数 (ACOS, LENGTH, MAX, ...) 既知の不具合