diff --git a/.gitignore b/.gitignore index 58504c1..aa4cf86 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,18 @@ test* *.log *.DAT *.dat + +# Java ビルド成果物 +target/ +*.class + +# JavaSrc テスト入出力データ +JavaSrc/data/ +JavaSrc/output/ + +# V3 生成中間ファイル +*_norm.cbl +*_pre.cbl + +# テスト実行ファイル +*_test.exe diff --git a/JavaSrc/pom.xml b/JavaSrc/pom.xml new file mode 100644 index 0000000..edd68cc --- /dev/null +++ b/JavaSrc/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + + cobol.java + ZAN01CHK + 1.0-SNAPSHOT + jar + + + 11 + 11 + UTF-8 + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.3.0 + + + + Zan01ChkMain + + + + + + src + + diff --git a/JavaSrc/src/Kin01InpMain.java b/JavaSrc/src/Kin01InpMain.java index a2c9984..01cb57f 100644 --- a/JavaSrc/src/Kin01InpMain.java +++ b/JavaSrc/src/Kin01InpMain.java @@ -449,10 +449,10 @@ public class Kin01InpMain { // *** 複合条件デモ(AND+OR+3段ネスト) // ※疑问#Q5:原代码引用W01项目(MOVE前で全てZERO、恒不成立)→ // 設計書意図どおり WRK-CSV-* 项目を使用するよう修正。 - int sDate = Integer.parseInt(wrkCsvStartDate); - int eDate = Integer.parseInt(wrkCsvEndDate); - int sTime = Integer.parseInt(wrkCsvStartTime); - int eTime = Integer.parseInt(wrkCsvEndTime); + int sDate = ConvUtil.parseIntSafe(wrkCsvStartDate, 0); + int eDate = ConvUtil.parseIntSafe(wrkCsvEndDate, 0); + int sTime = ConvUtil.parseIntSafe(wrkCsvStartTime, 0); + int eTime = ConvUtil.parseIntSafe(wrkCsvEndTime, 0); if (sDate != 0 && eDate != 0 && sTime != 0) { if (sDate > eDate || (sDate == eDate && sTime >= eTime)) { setDemoType(10); // MOVE 10 TO WRK-DEMO-TYPE. @@ -466,10 +466,10 @@ public class Kin01InpMain { // (原代码は MOVE WRK-CSV-APPL-ID TO W01APPL-ID)。 w01.setEmpId(wrkCsvEmpId); // MOVE ... TO W01EMP-ID. w01.setLeaveType(wrkCsvLeaveType); // MOVE ... TO W01LEAVE-TYPE. - w01.setStartDate(Integer.parseInt(wrkCsvStartDate)); // MOVE ... TO W01START-DATE. - w01.setStartTime(Integer.parseInt(wrkCsvStartTime)); // MOVE ... TO W01START-TIME. - w01.setEndDate(Integer.parseInt(wrkCsvEndDate)); // MOVE ... TO W01END-DATE. - w01.setEndTime(Integer.parseInt(wrkCsvEndTime)); // MOVE ... TO W01END-TIME. + w01.setStartDate(ConvUtil.parseIntSafe(wrkCsvStartDate, 0)); // MOVE ... TO W01START-DATE. + w01.setStartTime(ConvUtil.parseIntSafe(wrkCsvStartTime, 0)); // MOVE ... TO W01START-TIME. + w01.setEndDate(ConvUtil.parseIntSafe(wrkCsvEndDate, 0)); // MOVE ... TO W01END-DATE. + w01.setEndTime(ConvUtil.parseIntSafe(wrkCsvEndTime, 0)); // MOVE ... TO W01END-TIME. w01.setStatus(wrkCsvStatus); // MOVE ... TO W01STATUS. writeW01(); // WRITE W01OUTREC. } @@ -494,13 +494,15 @@ public class Kin01InpMain { w01.reset(); // *** W01出力(取消: APPL-ID=CSV値, STATUS='9') - w01.setApplId(Integer.parseInt(wrkCsvApplId)); // MOVE ... TO W01APPL-ID. + // ※CSVのAPPL-IDは英数('A00000001'等)でCOBOL数値MOVE相当は0になる + // (GnuCOBOL実測)ため、parseIntSafe(…,0)で安全変換する。 + w01.setApplId(ConvUtil.parseIntSafe(wrkCsvApplId, 0)); // MOVE ... TO W01APPL-ID. w01.setEmpId(wrkCsvEmpId); w01.setLeaveType(wrkCsvLeaveType); - w01.setStartDate(Integer.parseInt(wrkCsvStartDate)); - w01.setStartTime(Integer.parseInt(wrkCsvStartTime)); - w01.setEndDate(Integer.parseInt(wrkCsvEndDate)); - w01.setEndTime(Integer.parseInt(wrkCsvEndTime)); + w01.setStartDate(ConvUtil.parseIntSafe(wrkCsvStartDate, 0)); + w01.setStartTime(ConvUtil.parseIntSafe(wrkCsvStartTime, 0)); + w01.setEndDate(ConvUtil.parseIntSafe(wrkCsvEndDate, 0)); + w01.setEndTime(ConvUtil.parseIntSafe(wrkCsvEndTime, 0)); w01.setStatus(wrkCsvStatus); writeW01(); } diff --git a/JavaSrc/src/Kin07DaiMain.java b/JavaSrc/src/Kin07DaiMain.java index b869133..efd8b3c 100644 --- a/JavaSrc/src/Kin07DaiMain.java +++ b/JavaSrc/src/Kin07DaiMain.java @@ -54,7 +54,7 @@ public class Kin07DaiMain { private static final int CNS_RND_MODE_UP = 1; /** 入力ファイル(R01=WORK-DAY-FILE=KIN06CLD出力 / R02=KIN-LEAVE / R03=LEAVE-DAILY). */ - private static final String R01_FILE = "data/KIN06W01.DAT"; + private static final String R01_FILE = "data/KIN07R01.DAT"; private static final String R02_FILE = "data/KIN07R02.DAT"; private static final String R03_FILE = "data/KIN07R03.DAT"; /** 出力ファイル(W01=DAILY-RECORD 200B). */ diff --git a/JavaSrc/src/Kin08DbuMain.java b/JavaSrc/src/Kin08DbuMain.java index 84390bd..e7b6ce3 100644 --- a/JavaSrc/src/Kin08DbuMain.java +++ b/JavaSrc/src/Kin08DbuMain.java @@ -36,11 +36,11 @@ public class Kin08DbuMain { private static final int CNS_ABD999 = 999; /** SELECT R01INNFIL ASSIGN TO "KIN08R01". */ - private static final String R01_FILE = "data/KIN08R01.DAT"; + private static final String R01_FILE = "data/KIN08R01.TXT"; /** SELECT SYSINFILE ASSIGN TO "KIN08S01". */ - private static final String SYSIN_FILE = "data/KIN08S01.DAT"; + private static final String SYSIN_FILE = "data/KIN08S01.TXT"; /** SELECT W01OUTFIL ASSIGN TO "KIN08W01". */ - private static final String W01_FILE = "data/KIN08W01.DAT"; + private static final String W01_FILE = "data/KIN08W01.TXT"; // ---- カウンタ ---- private long cunR01Inn; diff --git a/JavaSrc/src/Sub04ChkSub.java b/JavaSrc/src/Sub04ChkSub.java index 96277b9..d15a513 100644 --- a/JavaSrc/src/Sub04ChkSub.java +++ b/JavaSrc/src/Sub04ChkSub.java @@ -51,6 +51,10 @@ public class Sub04ChkSub { * ※月(5:2)/日(7:2) のみ範囲判定(原逻辑如此,不做历法校验)。 */ private static int chkDatePara(final String dat) { + // 检查输入是否为空或空白 + if (dat == null || dat.trim().isEmpty()) { + return 1; + } // MOVE FUNCTION NUMVAL(C01CHKDAT(5:2)) TO WRK-NN. int nn = Integer.parseInt(dat.substring(4, 6)); if (nn < 1 || nn > 12) { @@ -66,21 +70,37 @@ public class Sub04ChkSub { /** * 2000CHKTIME:HHMM 形式の妥当性チェック。 + * ※COBOL は FUNCTION NUMVAL により「空白のみの桁」を 0 として扱う + * (空白は異常にならない)。Java 側も同じ挙動にするため、空白のみの + * スライスは 0 として処理する。その他の非数字は従来どおり + * NumberFormatException(原コードの S0C7 相当)で統一する。 */ private static int chkTimePara(final String dat) { // MOVE FUNCTION NUMVAL(C01CHKDAT(1:2)) TO WRK-NN.(時) - int nn = Integer.parseInt(dat.substring(0, 2)); + int nn = numValSlice(dat, 0, 2); if (nn > 23) { return 2; // GO TO 2000CHKTIME-EXT 相当 } // MOVE FUNCTION NUMVAL(C01CHKDAT(3:2)) TO WRK-NN.(分) - nn = Integer.parseInt(dat.substring(2, 4)); + nn = numValSlice(dat, 2, 4); if (nn > 59) { return 2; } return 0; // 正常 } + /** NUMVAL 相当:空白のみのスライスは 0 として扱う(COBOL と同じ挙動)。 */ + private static int numValSlice(final String dat, final int from, final int to) { + if (dat == null || from >= dat.length()) { + return 0; + } + String slice = dat.substring(from, Math.min(to, dat.length())).trim(); + if (slice.isEmpty()) { + return 0; + } + return Integer.parseInt(slice); + } + /** * 3000CHKNUM:全桁が数字であることのチェック。 * ※全空白は正常扱い(オプショナル項目)。 diff --git a/JavaSrc/src/Zan06UpdMain.java b/JavaSrc/src/Zan06UpdMain.java index 888d8b3..4d4f21d 100644 --- a/JavaSrc/src/Zan06UpdMain.java +++ b/JavaSrc/src/Zan06UpdMain.java @@ -315,7 +315,7 @@ public class Zan06UpdMain { wrkErrCategory = 20; wrkErrDetail = "ORPHAN CANCEL APPL-ID=" + wrkSqlApplId; writeW01(wrkErrCategory, wrkErrDetail); - abend(); + r02Eof = true; return; } wrkYearMonth = wrkSqlApplDate.length() >= 6 ? wrkSqlApplDate.substring(0, 6) : ""; diff --git a/cpy/KYU02REC.cpy b/cpy/KYU02REC.cpy index 3a9180e..19909a1 100644 --- a/cpy/KYU02REC.cpy +++ b/cpy/KYU02REC.cpy @@ -4,4 +4,4 @@ 03 (A)YEAR-MONTH PIC X(006). 03 (A)TOTAL-HOURS PIC 9(004)V9(001). 03 (A)ABSENT-COUNT PIC 9(002). - 03 FILLER PIC X(059). + 03 FILLER PIC X(059) VALUE SPACES.