Showing posts with label COBOL loops. Show all posts
Showing posts with label COBOL loops. Show all posts

Thursday, 14 August 2014

COBOL PERFORM Statement: Inline, Out-of-Line, TIMES, UNTIL, and VARYING

COBOL PERFORM statement diagram showing BASIC PERFORM, PERFORM TIMES, PERFORM UNTIL, and PERFORM VARYING

A COBOL PERFORM statement either runs named paragraph logic and returns, or runs inline statements between PERFORM and END-PERFORM. That one verb is behind many batch loops, validation checks, table scans, and small reusable routines in production COBOL programs.

Pick the form that matches the loop.

What does PERFORM do in COBOL?

PERFORM transfers control to one or more statements and then returns control to the next executable statement. In older paragraph-style COBOL, that usually means PERFORM 2000-VALIDATE-CUSTOMER. In newer structured code, it often means inline logic ended by END-PERFORM.

This page is the overview. For deep loop-condition detail, use the separate COBOL PERFORM UNTIL guide. For counter-style table loops, use the PERFORM VARYING guide.

Inline PERFORM vs out-of-line PERFORM

An inline PERFORM keeps the statements directly in the current flow. It must end with END-PERFORM. An out-of-line PERFORM names a paragraph or section, branches to it, and returns when that performed range finishes.

Type How it is coded Good fit
Inline PERFORM PERFORM ... END-PERFORM Short logic that is easier to read in place
Out-of-line PERFORM PERFORM paragraph-name Reusable logic or longer processing steps

Basic PERFORM example

A basic PERFORM runs the named paragraph once. This is common in old batch programs where each paragraph has a single job: initialize, read, validate, calculate, write, and close.

PROCEDURE DIVISION.
PERFORM 1000-INITIALIZE
PERFORM 2000-PROCESS-FILE
PERFORM 9000-CLOSE-FILES
GOBACK.
1000-INITIALIZE.
OPEN INPUT INFILE
OUTPUT OUTFILE.

Keep out-of-line paragraphs outside accidental fall-through paths. A paragraph that sits directly after the main flow can run once by PERFORM and again by ordinary sequential flow if the program is structured badly.

Inline PERFORM example

Inline PERFORM is clean for small checks because the reader does not need to jump to another paragraph. It also makes scope clear when paired with END-PERFORM.

PERFORM
IF WS-AMOUNT > ZERO
ADD WS-AMOUNT TO WS-TOTAL
ELSE
ADD 1 TO WS-ERROR-COUNT
END-IF
END-PERFORM

Use explicit scope terminators such as END-IF inside inline logic. That helps avoid bugs when another condition or loop is added later.

PERFORM TIMES example

PERFORM TIMES runs logic a fixed number of times. IBM documents that if the count is zero or negative when the statement starts, control passes to the statement after the PERFORM.

PERFORM 5 TIMES
DISPLAY "RETRYING FILE OPEN"
END-PERFORM

This form fits retry loops, small counters, test data generation, and repeatable validation. If the loop needs to stop based on a condition, use PERFORM UNTIL instead.

PERFORM UNTIL example

PERFORM UNTIL repeats while a condition is false, then stops when the condition becomes true. If neither TEST BEFORE nor TEST AFTER is specified, COBOL assumes TEST BEFORE.

PERFORM UNTIL END-OF-FILE
READ INFILE
AT END
SET END-OF-FILE TO TRUE
NOT AT END
PERFORM 3000-PROCESS-RECORD
END-READ
END-PERFORM

For file processing, always make the loop exit visible. A missing AT END action or a flag that never changes can create an endless loop in a batch job.

PERFORM VARYING example

PERFORM VARYING changes a counter or index each time through the loop. It is common with COBOL tables, especially when checking each occurrence of an array-like structure.

PERFORM VARYING WS-SUB FROM 1 BY 1
UNTIL WS-SUB > WS-MAX-ITEMS
IF ITEM-CODE(WS-SUB) = SPACES
ADD 1 TO WS-MISSING-COUNT
END-IF
END-PERFORM

Check the starting value, step value, and stop condition together. If WS-SUB starts at 1 and increases by 1, the condition should eventually become true.

PERFORM THRU warning

PERFORM paragraph-1 THRU paragraph-2 runs a range of paragraphs. It appears in many older systems, but it can be harder to maintain because adding a paragraph inside the range changes what the PERFORM runs. Prefer a single performed paragraph that calls smaller paragraphs when the codebase allows it.

Common mistakes

Recursive PERFORM

A performed paragraph must not cause itself to be performed. IBM warns that recursive PERFORM can produce unpredictable results. In plain terms, do not let 1000-MAIN perform 1000-MAIN again.

Mixing inline and out-of-line syntax

If the PERFORM names a paragraph, do not also put inline imperative statements and END-PERFORM on the same statement. Pick one style for that statement.

Hiding the loop exit

Every loop should show how it ends. For file loops, the AT END path should set a flag. For counter loops, the counter must move toward the end condition.

Related Mainframe Forum guides

Use this page as the PERFORM overview, then read COBOL Basic PERFORM, COBOL PERFORM TIMES, COBOL PERFORM UNTIL, and COBOL PERFORM VARYING. For related control logic, see COBOL IF Statement and COBOL EVALUATE Statement.

External references

IBM documents the formal rules in the Enterprise COBOL PERFORM statement, choosing inline or out-of-line PERFORM, and PERFORM TIMES pages.

FAQ

What is PERFORM in COBOL?

PERFORM runs inline statements or named procedure logic, then returns control to the next executable statement after the performed work finishes.

What is the difference between inline and out-of-line PERFORM?

Inline PERFORM keeps the logic in place and ends with END-PERFORM. Out-of-line PERFORM names a paragraph or section and branches to that procedure.

When should I use PERFORM TIMES?

Use PERFORM TIMES when the number of repeats is known before the loop starts, such as five retry attempts or ten test records.

When should I use PERFORM VARYING?

Use PERFORM VARYING when a counter or index must change on each pass, especially when processing a COBOL table.

Monday, 28 July 2014

COBOL PERFORM UNTIL: TEST BEFORE, TEST AFTER, and Loop Examples

A file-reading loop usually stops when the end-of-file flag becomes true. In COBOL, that pattern is often written with PERFORM UNTIL: run the statements again and again until the condition is satisfied.
COBOL PERFORM UNTIL loop showing TEST BEFORE and TEST AFTER behavior
PERFORM UNTIL stops when the condition is true.

This guide explains the UNTIL phrase of the COBOL PERFORM statement with simple examples. It keeps the focus on loop control: the condition, TEST BEFORE, TEST AFTER, inline loops, paragraph loops, and the mistakes that cause endless loops.

What PERFORM UNTIL Means

PERFORM UNTIL repeats a block of code or a named paragraph until a condition is true. IBM documents that when the condition is true, control passes to the next executable statement after the PERFORM.

PERFORM UNTIL END-OF-FILE
READ CUSTOMER-FILE
AT END
SET END-OF-FILE TO TRUE
NOT AT END
PERFORM 200-PROCESS-CUSTOMER
END-READ
END-PERFORM.

The loop continues while END-OF-FILE is false. It stops after the READ reaches end of file and the program sets the condition-name to true.

PERFORM UNTIL Syntax

The inline form keeps the looped statements directly under the PERFORM. It ends with END-PERFORM, which makes the loop boundary easy to see.

PERFORM [WITH TEST BEFORE | WITH TEST AFTER]
UNTIL condition
statement-1
statement-2
END-PERFORM.

The out-of-line form runs a paragraph or a range of paragraphs until the condition becomes true.

PERFORM 300-CALCULATE-TOTAL
UNTIL WS-DONE = "Y".

TEST BEFORE Is the Default

If you do not code WITH TEST BEFORE or WITH TEST AFTER, COBOL assumes TEST BEFORE. The condition is checked before the first execution. If the condition is already true, the loop body does not run at all.

MOVE 6 TO WS-COUNT.

PERFORM WITH TEST BEFORE
UNTIL WS-COUNT > 5
DISPLAY "COUNT=" WS-COUNT
ADD 1 TO WS-COUNT
END-PERFORM.

This loop displays nothing because WS-COUNT > 5 is already true before the loop starts. That behavior is correct, but it surprises many beginners.

TEST AFTER Runs at Least Once

WITH TEST AFTER checks the condition after the statements run. That means the body runs at least once, even when the condition is already true at entry.

MOVE 6 TO WS-COUNT.

PERFORM WITH TEST AFTER
UNTIL WS-COUNT > 5
DISPLAY "COUNT=" WS-COUNT
ADD 1 TO WS-COUNT
END-PERFORM.

This loop displays one line for COUNT=6, then stops. Use TEST AFTER only when one execution is required, such as prompting once before checking whether the user wants to continue.

File Reading Example

The most common mainframe use is a file loop. The file status and end-of-file flag should be initialized before the loop, then changed inside the loop.

01 WS-CUSTOMER-STATUS PIC X(02).
01 WS-END-OF-FILE PIC X VALUE "N".
88 END-OF-FILE VALUE "Y".
88 MORE-RECORDS VALUE "N".
PROCEDURE DIVISION.
SET MORE-RECORDS TO TRUE.
PERFORM UNTIL END-OF-FILE
READ CUSTOMER-FILE
AT END
SET END-OF-FILE TO TRUE
NOT AT END
PERFORM 200-PROCESS-CUSTOMER
END-READ
END-PERFORM.

This pattern is readable because the condition says what stops the loop. The loop does not depend on a hidden counter or an unclear flag name.

Counter Loop Example

PERFORM UNTIL can also control a counter. Initialize the counter before the loop and change it inside the loop. Without the change, the loop can run forever.

MOVE 1 TO WS-SUB.

PERFORM UNTIL WS-SUB > 10
DISPLAY "TABLE ENTRY " WS-SUB
ADD 1 TO WS-SUB
END-PERFORM.

For a pure counter loop, PERFORM VARYING may be clearer. Use the plain UNTIL form when the stop condition is tied to a flag, file status, response code, or business rule.

Inline PERFORM vs Paragraph PERFORM

FormUse it whenWatch for
Inline PERFORM UNTILThe loop body is short and belongs in one place.Use END-PERFORM and keep nested statements readable.
Paragraph PERFORM UNTILThe loop body is reused or has a clear paragraph name.Avoid wide THRU ranges that make control flow hard to follow.

IBM notes that Enterprise COBOL supports both inline and out-of-line PERFORM. For modern code, a short inline loop is often easier to read, while a named paragraph can still be useful for a business step such as 200-PROCESS-CUSTOMER.

PERFORM UNTIL EXIT

UNTIL EXIT creates a loop that does not end from a normal condition. IBM warns that the program must reach a real escape path. In an inline loop, that usually means EXIT PERFORM.

PERFORM UNTIL EXIT
ACCEPT WS-REPLY
IF WS-REPLY = "Q"
EXIT PERFORM
END-IF
PERFORM 100-HANDLE-REPLY
END-PERFORM.

Use this form sparingly. A named condition such as UNTIL END-OF-FILE or UNTIL WS-REPLY = "Q" is usually easier for the next developer to inspect.

Common Mistakes

Forgetting to Change the Loop Condition

If the condition never becomes true, the loop never ends. Update the counter, set the end-of-file flag, or change the response field inside the loop.

Using TEST AFTER by Accident

TEST AFTER guarantees one execution. That is useful only when one pass is required. For file reads and most validation loops, TEST BEFORE is usually safer.

Hiding Logic in a Wide THRU Range

PERFORM A-PARA THRU Z-PARA can execute every paragraph between those names. Keep paragraph ranges tight, or use inline PERFORM when the loop belongs in one place.

Related COBOL Lessons

For the broader loop family, read COBOL PERFORM statement, COBOL basic PERFORM, COBOL PERFORM TIMES phrase, and PERFORM VARYING in COBOL. For condition logic, continue with COBOL IF statement and COBOL EVALUATE statement.

FAQ

What is PERFORM UNTIL in COBOL?

PERFORM UNTIL repeats a block of statements or a paragraph until the specified condition becomes true.

Is TEST BEFORE or TEST AFTER the default?

TEST BEFORE is the default. COBOL checks the condition before the first execution unless WITH TEST AFTER is coded.

When should I use TEST AFTER?

Use TEST AFTER when the loop body must run at least once, such as asking for input once before checking whether the user wants to quit.

How do I prevent an endless PERFORM UNTIL loop?

Initialize the condition before the loop and make sure the loop body can make the condition true. For file loops, set an end-of-file flag in the AT END path.

References

For exact syntax and current compiler behavior, use IBM documentation for PERFORM with UNTIL phrase, using PERFORM, and IBM's coding a loop examples.

Write the condition so it says exactly when the loop must stop, then make sure the code inside the loop can make that condition true.

New In-feed ads