Skip to content

Commit 4ae45f3

Browse files
committed
#801 Allow gaps between segment redefined fields as long as they have a single common base redefine.
1 parent a6c0057 commit 4ae45f3

File tree

2 files changed

+87
-1
lines changed

2 files changed

+87
-1
lines changed

cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/parser/asttransform/SegmentRedefinesMarker.scala

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,20 @@ class SegmentRedefinesMarker(segmentRedefines: Seq[String]) extends AstTransform
7272
if (foundRedefines.contains(g.name)) {
7373
throw new IllegalStateException(s"Duplicate segment redefine field '${g.name}' found.")
7474
}
75+
76+
if (redefineGroupState == 1 && g.redefines.isEmpty)
77+
throw new IllegalStateException(s"The segment redefine field '${g.name}' is not a REDEFINE or redefined by another field.")
78+
7579
ensureSegmentRedefinesAreIneGroup(g.name, isCurrentFieldASegmentRedefine = true)
7680
foundRedefines += g.name
7781
g.withUpdatedIsSegmentRedefine(true)
7882
} else {
79-
ensureSegmentRedefinesAreIneGroup(g.name, isCurrentFieldASegmentRedefine = false)
83+
// Allow redefines in between segment redefines.
84+
val fieldMightBeRedefine = if (redefineGroupState == 1 && g.redefines.nonEmpty)
85+
true
86+
else
87+
false
88+
ensureSegmentRedefinesAreIneGroup(g.name, isCurrentFieldASegmentRedefine = fieldMightBeRedefine)
8089
// Check nested fields recursively only if segment redefines hasn't been found so far.
8190
if (redefineGroupState == 0) {
8291
processGroupFields(g)

cobol-parser/src/test/scala/za/co/absa/cobrix/cobol/parser/parse/SegmentRedefinesSpec.scala

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,33 @@ class SegmentRedefinesSpec extends AnyFunSuite {
8888
assert(!parsedCopybook.ast.children.head.asInstanceOf[Group].children(4).asInstanceOf[Group].isSegmentRedefine)
8989
}
9090

91+
test ("Test allow gaps in segment redefines as long as they are in the same group") {
92+
val copybook =
93+
""" 01 RECORD.
94+
| 02 A-RECORD.
95+
| 03 FIELD0 PIC X(2).
96+
| 02 SEGMENT-A.
97+
| 03 FIELD1 PIC X(2).
98+
| 02 SEGMENT-B REDEFINES SEGMENT-A.
99+
| 03 FIELD1 PIC X(2).
100+
| 02 SEGMENT-C REDEFINES SEGMENT-A.
101+
| 03 FIELD4 PICTURE S9(6)USAGE COMP.
102+
| 02 SEGMENT-D REDEFINES SEGMENT-A.
103+
| 03 FIELD4 PICTURE S9(6)USAGE COMP.
104+
| 02 Z-RECORD.
105+
| 03 FIELD5 PIC X(2).
106+
""".stripMargin
107+
108+
val segmentRedefines = "SEGMENT-A" :: "SEGMENT-C" :: "SEGMENT-D" :: Nil
109+
110+
val parsedCopybook = CopybookParser.parseTree(copybook, dropGroupFillers = false, dropValueFillers = true, fillerNamingPolicy = FillerNamingPolicy.SequenceNumbers, segmentRedefines)
111+
112+
assert(!parsedCopybook.ast.children.head.asInstanceOf[Group].children(0).asInstanceOf[Group].isSegmentRedefine)
113+
assert(parsedCopybook.ast.children.head.asInstanceOf[Group].children(1).asInstanceOf[Group].isSegmentRedefine)
114+
assert(!parsedCopybook.ast.children.head.asInstanceOf[Group].children(2).asInstanceOf[Group].isSegmentRedefine)
115+
assert(parsedCopybook.ast.children.head.asInstanceOf[Group].children(3).asInstanceOf[Group].isSegmentRedefine)
116+
}
117+
91118
test ("Test segment redefines should be in the same redefined group") {
92119
val copybook =
93120
""" 01 RECORD.
@@ -115,5 +142,55 @@ class SegmentRedefinesSpec extends AnyFunSuite {
115142
assert(exception1.getMessage.contains("The 'SEGMENT_C' field is specified to be a segment redefine."))
116143
}
117144

145+
test ("Test first segment should be redefined") {
146+
val copybook =
147+
""" 01 RECORD.
148+
| 02 A-RECORD.
149+
| 03 FIELD0 PIC X(2).
150+
| 02 SEGMENT-A.
151+
| 03 FIELD1 PIC X(2).
152+
| 02 SEGMENT-B.
153+
| 03 FIELD1 PIC X(2).
154+
| 02 SEGMENT-C REDEFINES SEGMENT-B.
155+
| 03 FIELD4 PICTURE S9(6)USAGE COMP.
156+
| 02 SEGMENT-D REDEFINES SEGMENT-C.
157+
| 03 FIELD4 PICTURE S9(6)USAGE COMP.
158+
| 02 Z-RECORD.
159+
| 03 FIELD5 PIC X(2).
160+
""".stripMargin
161+
162+
val segmentRedefines = "SEGMENT-A" :: "SEGMENT-B" :: "SEGMENT-C" :: "SEGMENT-D" :: Nil
163+
164+
val exception1 = intercept[IllegalStateException] {
165+
CopybookParser.parseTree(copybook, dropGroupFillers = false, dropValueFillers = true, fillerNamingPolicy = FillerNamingPolicy.SequenceNumbers, segmentRedefines)
166+
}
167+
assert(exception1.getMessage.contains("The following segment redefines not found: [ SEGMENT_A ]."))
168+
}
169+
170+
test ("Test don't allow non-redefined fields in between segment redefines") {
171+
val copybook =
172+
""" 01 RECORD.
173+
| 02 A-RECORD.
174+
| 03 FIELD0 PIC X(2).
175+
| 02 SEGMENT-A.
176+
| 03 FIELD1 PIC X(2).
177+
| 02 SEGMENT-B REDEFINES SEGMENT-A.
178+
| 03 FIELD1 PIC X(2).
179+
| 02 SEGMENT-C.
180+
| 03 FIELD4 PICTURE S9(6)USAGE COMP.
181+
| 02 SEGMENT-D REDEFINES SEGMENT-C.
182+
| 03 FIELD4 PICTURE S9(6)USAGE COMP.
183+
| 02 Z-RECORD.
184+
| 03 FIELD5 PIC X(2).
185+
""".stripMargin
186+
187+
val segmentRedefines = "SEGMENT-A" :: "SEGMENT-B" :: "SEGMENT-C" :: "SEGMENT-D" :: Nil
188+
189+
val exception1 = intercept[IllegalStateException] {
190+
CopybookParser.parseTree(copybook, dropGroupFillers = false, dropValueFillers = true, fillerNamingPolicy = FillerNamingPolicy.SequenceNumbers, segmentRedefines)
191+
}
192+
assert(exception1.getMessage.contains("The segment redefine field 'SEGMENT_C' is not a REDEFINE or redefined by another field."))
193+
}
194+
118195

119196
}

0 commit comments

Comments
 (0)