Skip to content

Commit

Permalink
feat: Implementation of STARTBR statement in CICS (#2633)
Browse files Browse the repository at this point in the history
  • Loading branch information
ilidio-lopes authored Jan 7, 2025
1 parent 8beccfe commit 89dbb59
Show file tree
Hide file tree
Showing 4 changed files with 254 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -804,8 +804,9 @@ cics_start_brexit: BREXIT name? (TRANSID cics_name | BRDATA cics_data_area | BRD
cics_zero_digit: LPARENCHAR ZERO_DIGIT RPARENCHAR;

/** STARTBR */
cics_startbr: STARTBR cics_file_name (RIDFLD cics_data_area | KEYLENGTH cics_data_value | GENERIC | REQID cics_data_value |
SYSID cics_data_area | DEBKEY | DEBREC | RBA | RBN | XRBA | GTEQ | EQUAL | cics_handle_response)+;
cics_startbr: STARTBR cics_startbr_options;
cics_startbr_options: ((FILE | DATASET) cics_name | (RIDFLD | SYSID) cics_data_area | (KEYLENGTH | REQID) cics_data_value | GENERIC |
DEBKEY | DEBREC | RBA | RRN | XRBA | GTEQ | EQUAL | cics_handle_response)+;

/** STARTBROWSE ACTIVITY / CONTAINER / EVENT / PROCESS */
cics_startbrowse: STARTBROWSE (cics_startbrowse_activity | cics_startbrowse_container | cics_startbrowse_event |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,9 @@ public CICSOptionsCheckUtility(DialectProcessingContext context, List<SyntaxErro
optionsMap.put(
CICSSignalOptionsCheckUtility.RULE_INDEX,
new CICSSignalOptionsCheckUtility(context, errors));
optionsMap.put(
CICSStartbrOptionsCheckUtility.RULE_INDEX,
new CICSStartbrOptionsCheckUtility(context, errors));
optionsMap.put(
CICSIgnoreOptionsCheckUtility.RULE_INDEX,
new CICSIgnoreOptionsCheckUtility(context, errors));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2024 Broadcom.
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Broadcom, Inc. - initial API and implementation
*
*/
package org.eclipse.lsp.cobol.implicitDialects.cics.utility;

import org.antlr.v4.runtime.ParserRuleContext;
import org.eclipse.lsp.cobol.common.dialects.DialectProcessingContext;
import org.eclipse.lsp.cobol.common.error.ErrorSeverity;
import org.eclipse.lsp.cobol.common.error.SyntaxError;
import org.eclipse.lsp.cobol.implicitDialects.cics.CICSLexer;
import org.eclipse.lsp.cobol.implicitDialects.cics.CICSParser;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.eclipse.lsp.cobol.implicitDialects.cics.CICSParser.RULE_cics_startbr;

/** Checks CICS STARTBR rules for required and invalid options */
public class CICSStartbrOptionsCheckUtility extends CICSOptionsCheckBaseUtility {
public static final int RULE_INDEX = RULE_cics_startbr;

private static final Map<Integer, ErrorSeverity> DUPLICATE_CHECK_OPTIONS =
new HashMap<Integer, ErrorSeverity>() {
{
put(CICSLexer.FILE, ErrorSeverity.ERROR);
put(CICSLexer.DATASET, ErrorSeverity.ERROR);
put(CICSLexer.RIDFLD, ErrorSeverity.ERROR);
put(CICSLexer.KEYLENGTH, ErrorSeverity.ERROR);
put(CICSLexer.GENERIC, ErrorSeverity.WARNING);
put(CICSLexer.REQID, ErrorSeverity.ERROR);
put(CICSLexer.SYSID, ErrorSeverity.ERROR);
put(CICSLexer.DEBKEY, ErrorSeverity.WARNING);
put(CICSLexer.DEBREC, ErrorSeverity.WARNING);
put(CICSLexer.RBA, ErrorSeverity.WARNING);
put(CICSLexer.RRN, ErrorSeverity.WARNING);
put(CICSLexer.XRBA, ErrorSeverity.WARNING);
put(CICSLexer.GTEQ, ErrorSeverity.WARNING);
put(CICSLexer.EQUAL, ErrorSeverity.WARNING);
}
};

public CICSStartbrOptionsCheckUtility(DialectProcessingContext context, List<SyntaxError> errors) {
super(context, errors, DUPLICATE_CHECK_OPTIONS);
}

/**
* Entrypoint to check CICS STARTBR rule options
*
* @param ctx ParserRuleContext subclass containing options
* @param <E> A subclass of ParserRuleContext
*/
public <E extends ParserRuleContext> void checkOptions(E ctx) {
if (ctx instanceof CICSParser.Cics_startbr_optionsContext) {
checkStartbr((CICSParser.Cics_startbr_optionsContext) ctx);
}
checkDuplicates(ctx);
}

@SuppressWarnings("unchecked")
private void checkStartbr(CICSParser.Cics_startbr_optionsContext ctx) {
checkHasExactlyOneOption("FILE or DATASET", ctx, ctx.FILE(), ctx.DATASET());
checkHasMandatoryOptions(ctx.RIDFLD(), ctx, "RIDFLD");
checkHasMutuallyExclusiveOptions("DEBKEY, DEBREC, RBA, RRN, or XRBA",
ctx.DEBKEY(), ctx.DEBREC(), ctx.RBA(), ctx.RRN(), ctx.XRBA());
checkHasMutuallyExclusiveOptions("GTEQ or EQUAL", ctx.GTEQ(), ctx.EQUAL());
if (!ctx.GENERIC().isEmpty()) {
checkHasMandatoryOptions(ctx.KEYLENGTH(), ctx, "KEYLENGTH");
}
if (!ctx.SYSID().isEmpty()) {
checkHasExactlyOneOption("KEYLENGTH, RBA, RRN, or XRBA", ctx, ctx.KEYLENGTH(), ctx.RBA(), ctx.RRN(), ctx.XRBA());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
* Copyright (c) 2024 Broadcom.
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Broadcom, Inc. - initial API and implementation
*
*/
package org.eclipse.lsp.cobol.usecases;

import com.google.common.collect.ImmutableMap;
import org.eclipse.lsp.cobol.common.error.ErrorSource;
import org.eclipse.lsp.cobol.usecases.common.CICSTestUtils;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.DiagnosticSeverity;
import org.eclipse.lsp4j.Range;
import org.junit.jupiter.api.Test;

/**
* Test CICS STARTBR command. Documentation link: <a
* href="https://www.ibm.com/docs/en/cics-ts/6.x?topic=summary-startbr">STARTBR Command</a>
*
* <p>This class tests the STARTBR command.
*/
public class TestCICSStartbr {
private static final String STARTBR_VALID_MINIMAL =
"STARTBR FILE({$varOne}) RIDFLD({$varTwo})";

private static final String STARTBR_DATASET_VALID =
"STARTBR DATASET({$varOne}) RIDFLD({$varTwo})";

private static final String STARTBR_INVALID_NO_KEYLENGTH =
"STARTBR {_FILE({$varOne}) RIDFLD({$varTwo}) GENERIC|errorOne_}";

private static final String STARTBR_VALID_FULL =
"STARTBR FILE({$varOne}) RIDFLD({$varTwo}) KEYLENGTH({$varThree}) GENERIC REQID({$varFour}) SYSID({$varFive}) DEBKEY GTEQ";

private static final String STARTBR_SYSID_INVALID =
"STARTBR {_FILE({$varOne}) RIDFLD({$varTwo}) SYSID({$varFive}) GTEQ|errorOne_}";

private static final String STARTBR_INVALID_NO_FILE =
"STARTBR {_RIDFLD({$varTwo}) KEYLENGTH({$varOne}) GENERIC|errorOne_}";

private static final String STARTBR_INVALID_NO_RIDFLD =
"STARTBR {_FILE({$varOne}) KEYLENGTH({$varTwo}) GENERIC|errorOne_}";

private static final String STARTBR_INVALID_MULTIPLE_POSITIONING =
"STARTBR FILE({$varOne}) RIDFLD({$varTwo}) {DEBKEY|errorOne} {RBA|errorTwo}";

private static final String STARTBR_INVALID_MULTIPLE_COMPARISON =
"STARTBR FILE({$varOne}) RIDFLD({$varTwo}) {GTEQ|errorOne} {EQUAL|errorTwo}";

@Test
void testStartbrValidMinimal() {
CICSTestUtils.noErrorTest(STARTBR_VALID_MINIMAL);
}

@Test
void testStartbrDatasetValid() {
CICSTestUtils.noErrorTest(STARTBR_DATASET_VALID);
}

@Test
void testStartbrInvalidNoKeylength() {
CICSTestUtils.errorTest(
STARTBR_INVALID_NO_KEYLENGTH,
ImmutableMap.of(
"errorOne",
new Diagnostic(
new Range(),
"Missing required option: KEYLENGTH",
DiagnosticSeverity.Error,
ErrorSource.PARSING.getText())));
}

@Test
void testStartbrSysidInvalid() {
CICSTestUtils.errorTest(
STARTBR_SYSID_INVALID,
ImmutableMap.of(
"errorOne",
new Diagnostic(
new Range(),
"Exactly one option required, none provided: KEYLENGTH, RBA, RRN, or XRBA",
DiagnosticSeverity.Error,
ErrorSource.PARSING.getText())));
}

@Test
void testStartbrValidFull() {
CICSTestUtils.noErrorTest(STARTBR_VALID_FULL);
}

@Test
void testStartbrInvalidNoFile() {
CICSTestUtils.errorTest(
STARTBR_INVALID_NO_FILE,
ImmutableMap.of(
"errorOne",
new Diagnostic(
new Range(),
"Exactly one option required, none provided: FILE or DATASET",
DiagnosticSeverity.Error,
ErrorSource.PARSING.getText())));
}

@Test
void testStartbrInvalidNoRidfld() {
CICSTestUtils.errorTest(
STARTBR_INVALID_NO_RIDFLD,
ImmutableMap.of(
"errorOne",
new Diagnostic(
new Range(),
"Missing required option: RIDFLD",
DiagnosticSeverity.Error,
ErrorSource.PARSING.getText())));
}

@Test
void testStartbrInvalidMultiplePositioning() {
CICSTestUtils.errorTest(
STARTBR_INVALID_MULTIPLE_POSITIONING,
ImmutableMap.of(
"errorOne",
new Diagnostic(
new Range(),
"Exactly one option required, options are mutually exclusive: DEBKEY, DEBREC, RBA, RRN, or XRBA",
DiagnosticSeverity.Error,
ErrorSource.PARSING.getText()),
"errorTwo",
new Diagnostic(
new Range(),
"Exactly one option required, options are mutually exclusive: DEBKEY, DEBREC, RBA, RRN, or XRBA",
DiagnosticSeverity.Error,
ErrorSource.PARSING.getText())));
}

@Test
void testStartbrInvalidMultipleComparison() {
CICSTestUtils.errorTest(
STARTBR_INVALID_MULTIPLE_COMPARISON,
ImmutableMap.of(
"errorOne",
new Diagnostic(
new Range(),
"Exactly one option required, options are mutually exclusive: GTEQ or EQUAL",
DiagnosticSeverity.Error,
ErrorSource.PARSING.getText()),
"errorTwo",
new Diagnostic(
new Range(),
"Exactly one option required, options are mutually exclusive: GTEQ or EQUAL",
DiagnosticSeverity.Error,
ErrorSource.PARSING.getText())));
}
}

0 comments on commit 89dbb59

Please sign in to comment.