ACCEPT, DISPLAY and Console I/O

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The reference material consulted while preparing these pages is listed in the section bibliography.

This page is written against ISO/IEC 1989:2023 (edition 3, January 2023), GnuCOBOL 3.2 and IBM Enterprise COBOL for z/OS 6.5 (PTFs through September 2026), and was checked on 2026-10-20. DISPLAY and ACCEPT are the oldest input and output statements of the language: they send a line to, or read a line from, the system’s standard devices without declaring a file. The line-oriented forms exist in every dialect. The command-line, environment-variable and positioned-screen forms, and the whole SCREEN SECTION (introduced by COBOL 2002), are not part of Enterprise COBOL for z/OS 6.5, whose Language Reference has no SCREEN SECTION, no CRT STATUS and no ARGUMENT-VALUE, COMMAND-LINE or ENVIRONMENT-VALUE device names; on z/OS the same needs are met by JCL (SYSIN, SYSOUT, PARM) and, for terminals, by CICS and 3270 maps. Every portable example was compiled with cobc -x -Wall in GnuCOBOL 3.2.0 (and with -std=ibm where it says so) with no warnings, run, and the output and diagnostics shown are real. Examples labelled "z/OS; not run here" cannot run on the machine that wrote this page. The examples use the Circulation copybooks (MEMBREC, LOANREC) of the whole section, and the first program of Getting Started already uses ACCEPT; the file I/O that DISPLAY and ACCEPT deliberately avoid is in File Concepts, SELECT and FD, and ACCEPT ... FROM DATE and TIME are in Dates and Times.

Where the data goes

flowchart LR subgraph GC["GnuCOBOL 3.2 on Linux, macOS or Windows"] direction LR G1["ACCEPT without FROM, FROM CONSOLE, STDIN or SYSIN"] --> G0["COBOL program"] G0 --> G2["DISPLAY without UPON, CONSOLE, STDOUT or SYSOUT: standard output"] G0 --> G3["DISPLAY UPON SYSERR or STDERR: standard error"] G4["Command line, environment variables"] --> G0 G0 <--> G5["Screen: extended ACCEPT and DISPLAY, SCREEN SECTION"] end subgraph ZOS["Enterprise COBOL on z/OS, batch"] direction LR Z1["SYSIN DD: ACCEPT FROM SYSIN"] --> Z0["COBOL program"] Z2["PARM on EXEC: LINKAGE SECTION"] --> Z0 Z0 --> Z3["SYSOUT DD (or the OUTDD ddname): DISPLAY"] Z0 --> Z4["Console: operator messages and replies"] end

The figure contrasts the two environments. In GnuCOBOL the program talks to the process’s standard streams, its arguments and its environment, and to the terminal for screens. On z/OS the same statements are bound to data definition (DD) statements of the job, and the program’s arguments arrive as the PARM string.

The forms at a glance

Need GnuCOBOL 3.2 Enterprise COBOL for z/OS 6.5

Print a line

DISPLAY a b c; no UPON means CONSOLE, which is standard output

DISPLAY a b c; no UPON means the system logical output device (SYSOUT, or the OUTDD ddname)

Print to another stream

UPON CONSOLE, PRINTER, STDERR, STDOUT, SYSERR, SYSLIST, SYSLST or SYSOUT, or a mnemonic name for one of them

UPON SYSOUT, SYSLIST, SYSLST, SYSPUNCH, SYSPCH or CONSOLE, or a mnemonic name (an IBM extension to the 85 standard)

Print without the line break

WITH NO ADVANCING

WITH NO ADVANCING; to a ddname the next record starts with the printer control character +

Read a line

ACCEPT x, ACCEPT x FROM CONSOLE, STDIN, SYSIN or SYSIPT (or a mnemonic name)

ACCEPT x FROM SYSIN, SYSIPT or CONSOLE (or a mnemonic name); the record length of the device decides how much is read

Date and time

ACCEPT x FROM DATE, DATE YYYYMMDD, DAY, DAY YYYYDDD, DAY-OF-WEEK, TIME

The same six conceptual items (see Dates and Times)

Program arguments

ACCEPT x FROM ARGUMENT-NUMBER, ARGUMENT-VALUE, COMMAND-LINE; DISPLAY n UPON ARGUMENT-NUMBER

The PARM string through the LINKAGE SECTION, or the Language Environment services CEE3PRM and CEE3PR2; on z/OS UNIX an argument count and two pointer arrays

Environment variables

ACCEPT x FROM ENVIRONMENT "NAME"; or DISPLAY "NAME" UPON ENVIRONMENT-NAME and ACCEPT x FROM ENVIRONMENT-VALUE; DISPLAY "V" UPON ENVIRONMENT-VALUE sets one

Under z/OS UNIX the C functions getenv() and setenv() called from COBOL

Formatted screen

SCREEN SECTION, ACCEPT and DISPLAY of screen items, extended ACCEPT/DISPLAY with AT LINE ... COLUMN, CRT STATUS

Not available; online screens are CICS and BMS maps

DISPLAY

The format is DISPLAY followed by one or more literals or identifiers, an optional UPON device and an optional WITH NO ADVANCING. The operands are sent to the device left to right as one record, and when the statement ends the device moves to the start of the next line unless WITH NO ADVANCING was written. In GnuCOBOL, ON EXCEPTION, NOT ON EXCEPTION and END-DISPLAY are also accepted. A figurative constant operand is shown once, not repeated. The two programs below use the member record layout from the copybook MEMBREC and show the UPON devices.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. DISPLAY1.
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       SPECIAL-NAMES.
           CONSOLE IS OPERATOR-LOG.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
           COPY MEMBREC.
       01  WS-COUNT            PIC 9(3) VALUE 4.
       PROCEDURE DIVISION.
       MAIN-PARA.
           MOVE 101 TO MEMBER-ID
           MOVE "Grace Hopper" TO MEMBER-NAME
           MOVE 12.50 TO MEMBER-FINES
           DISPLAY "Member " MEMBER-ID " " FUNCTION TRIM(MEMBER-NAME)
           DISPLAY "Fines due: " MEMBER-FINES
           DISPLAY "Loans in file: " WITH NO ADVANCING
           DISPLAY WS-COUNT
           DISPLAY "Rule: " ALL "-"
           DISPLAY "Nightly run started" UPON SYSOUT
           DISPLAY "Nightly run: warning, 1 rejected" UPON SYSERR
           DISPLAY "Operator: run complete" UPON OPERATOR-LOG
           GOBACK.

Standard output and standard error are separate streams. Running the program and keeping only standard output (./display1 2>/dev/null) prints:

Member 000101 Grace Hopper
Fines due: +00012.50
Loans in file: 004
Rule: -
Nightly run started
Operator: run complete

Keeping only standard error (./display1 2>&1 >/dev/null) prints the one line sent UPON SYSERR:

Nightly run: warning, 1 rejected

ALL "-" shows a single hyphen, as the IBM Language Reference says for a figurative constant in DISPLAY. UPON CONSOLE, SYSOUT and a mnemonic name for CONSOLE all land on standard output in GnuCOBOL; only SYSERR and STDERR use standard error. The numeric field MEMBER-FINES is shown with its sign and decimal point, which is the next topic.

What a numeric item looks like

DISPLAY writes data in its external form. IBM’s Language Reference says that binary and internal decimal items are converted to zoned decimal, that a negative signed value then carries a low-order sign overpunch (which can look like a letter or a brace on output), that the DISPSIGN compiler option can show the sign separately, that a COMP-1 item is shown as if it had the picture -.9(8)E-99 and a COMP-2 item as -.9(17)E-99, that a pointer is shown as a ten-digit number, and that an index cannot be displayed. GnuCOBOL always prints an explicit sign and, by default, the decimal point. The program below displays one value in five usages and a literal.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. DISPLAY2.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-ZONED            PIC S9(5)V99 VALUE -12.5.
       01  WS-PACKED           PIC S9(5)V99 COMP-3 VALUE -12.5.
       01  WS-BINARY           PIC S9(4) COMP VALUE -7.
       01  WS-EDITED           PIC -ZZ,ZZ9.99.
       01  WS-SEPARATE         PIC S9(3) SIGN LEADING SEPARATE VALUE -7.
       PROCEDURE DIVISION.
       MAIN-PARA.
           MOVE WS-ZONED TO WS-EDITED
           DISPLAY "zoned    [" WS-ZONED "]"
           DISPLAY "packed   [" WS-PACKED "]"
           DISPLAY "binary   [" WS-BINARY "]"
           DISPLAY "edited   [" WS-EDITED "]"
           DISPLAY "separate [" WS-SEPARATE "]"
           DISPLAY "literal  [" -12.5 "]"
           GOBACK.

With cobc -x -Wall display2.cob the output is:

zoned    [-00012.50]
packed   [-00012.50]
binary   [-0007]
edited   [-    12.50]
separate [-007]
literal  [-12.5]

With cobc -x -Wall -std=ibm display2.cob the decimal point disappears and the position of the sign changes, so the same source prints different text:

zoned    [0001250-]
packed   [-0001250]
binary   [-00007]
edited   [-    12.50]
separate [-007]
literal  [-125]

The zoned item and the packed item print differently under -std=ibm in this build, which is one more reason not to parse the text of a DISPLAY of a signed or scaled field. If a program writes numbers for another program to read, move them to a numeric-edited field with an explicit sign first (the edited line above is identical in both dialects), or write them to a file with a defined layout.

WITH NO ADVANCING

WITH NO ADVANCING suppresses the line break so that the next output continues on the same line; it is how a prompt stays next to the answer. IBM documents two meanings. Sent to a ddname, the next DISPLAY record starts with the printer control character + (suppress spacing before printing). Sent to stdout or stderr under z/OS UNIX, no newline is appended. On z/OS UNIX the unstructured stream is not split into records, and _IGZ_SYSOUT chooses between stdout (the default) and stderr.

Output sizes on z/OS

The Language Reference gives a default logical record size for each output device (120 characters for the system logical output device, 80 for the punch device, 100 for the console) and a maximum (255 characters for SYSOUT and the punch device, 100 for the console). A longer line is written as several records, and an operand that crosses the end of a record continues in the next one. Keep report lines short, and use a file with a WRITE for anything that must keep its layout; see Sequential Files.

ACCEPT from the system input

ACCEPT identifier reads one piece of input into a data item; with no FROM phrase it reads the system input device, and FROM selects SYSIN or SYSIPT (the system logical input unit), CONSOLE, or in GnuCOBOL also STDIN. IBM’s Language Reference states that there is no editing and no error checking of the incoming data. The program below reads one loan transaction from standard input, with the prompts written by DISPLAY ... WITH NO ADVANCING; SYSIN IS TRANS-INPUT in SPECIAL-NAMES gives the device a mnemonic name that ACCEPT can use.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. ACCEPT1.
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       SPECIAL-NAMES.
           SYSIN IS TRANS-INPUT.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
           COPY LOANREC.
       01  WS-TYPE-IN          PIC X(1).
       01  WS-MEMBER-IN        PIC X(6).
       01  WS-BOOK-ID          PIC 9(6).
       01  WS-LINES-READ       PIC 9(2) VALUE 0.
       PROCEDURE DIVISION.
       MAIN-PARA.
           DISPLAY "Transaction type (O or R): " WITH NO ADVANCING
           ACCEPT WS-TYPE-IN FROM TRANS-INPUT
           DISPLAY "Member id: " WITH NO ADVANCING
           ACCEPT WS-MEMBER-IN FROM SYSIN
           DISPLAY "Book id: " WITH NO ADVANCING
           ACCEPT WS-BOOK-ID FROM SYSIN
           DISPLAY SPACE
           MOVE WS-TYPE-IN TO LOAN-TYPE
           MOVE WS-MEMBER-IN TO LOAN-MEMBER-ID
           MOVE WS-BOOK-ID TO LOAN-BOOK-ID
           IF LOAN-CHECKOUT
              DISPLAY "Checkout: member " LOAN-MEMBER-ID
                 " takes book " LOAN-BOOK-ID
           ELSE
              DISPLAY "Return: book " LOAN-BOOK-ID
                 " from member " LOAN-MEMBER-ID
           END-IF
           GOBACK.

Because standard input is a pipe, nothing is echoed, so the three prompts run together on one line. Run as printf 'O\n000100\n1\n' | ./accept1:

Transaction type (O or R): Member id: Book id:
Checkout: member 000100 takes book 000001

Run with -std=ibm and the input R, 000101, 000002, the program compiles with no warnings and prints:

Transaction type (O or R): Member id: Book id:
Return: book 000002 from member 000101

If the input ends early, the remaining ACCEPT statements get no data. In GnuCOBOL 3.2.0 a field that cannot be filled is cleared (spaces for an alphanumeric item, zero for a numeric one). Run as printf 'O\n' | ./accept1, the second and third prompts get nothing:

Transaction type (O or R): Member id: Book id:
Checkout: member 000000 takes book 000000

Enterprise COBOL behaves differently: if end of file is reached before any data has moved to the receiving area, the receiving area keeps its previous contents. Test for end of input explicitly instead of relying on either behaviour; GnuCOBOL raises the exception condition, so ON EXCEPTION on the ACCEPT can detect it, as the next program shows.

How much is read, and how it is stored

The receiving item can be an alphanumeric or national group item or an elementary item with usage DISPLAY, DISPLAY-1 or NATIONAL (IBM). The two compilers read differently.

  • Enterprise COBOL. The system input device is read until the receiving area is filled or end of file is reached, and the records are concatenated: an ACCEPT into a 160-byte item reads two 80-byte SYSIN records, and an ACCEPT into a 6-byte item takes the first six bytes of a record and discards the rest. Fixed-length records are used whole, with no removal of leading or trailing blanks; for variable-length records the record descriptor word is removed. National items are not converted, except that input from the console is converted from the code page named by the CODEPAGE compiler option. A line read from the console is limited to 114 characters.

  • GnuCOBOL. One line is read for each ACCEPT. A numeric receiving item is filled by parsing the text as NUMVAL does, but ignoring trailing-sign formats.

The program below shows what happens with a short line, a long line, a decimal, text in a numeric field, an overflowing number, a negative number in an unsigned field, and the end of input. The receiving items start with values that are easy to recognize.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. ACCEPT2.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-CODE             PIC X(6) VALUE "XXXXXX".
       01  WS-FINE             PIC 9(3)V99 VALUE 999.99.
       01  WS-COUNT            PIC 9(3) VALUE 777.
       01  WS-READS            PIC 9(2) VALUE 0.
       PROCEDURE DIVISION.
       MAIN-PARA.
           ACCEPT WS-CODE
           DISPLAY "code  [" WS-CODE "]"
           ACCEPT WS-CODE
           DISPLAY "code  [" WS-CODE "]"
           ACCEPT WS-FINE
           DISPLAY "fine  [" WS-FINE "]"
           ACCEPT WS-FINE
           DISPLAY "fine  [" WS-FINE "]"
           ACCEPT WS-COUNT
           DISPLAY "count [" WS-COUNT "]"
           ACCEPT WS-COUNT
           DISPLAY "count [" WS-COUNT "]"
           ACCEPT WS-CODE
              ON EXCEPTION DISPLAY "no more input"
              NOT ON EXCEPTION DISPLAY "code  [" WS-CODE "]"
           END-ACCEPT
           DISPLAY "code  [" WS-CODE "]"
           GOBACK.

Run as printf 'AB\nLONGER-THAN-SIX\n12.5\nabc\n4567\n-4\n' | ./accept2:

code  [AB    ]
code  [LONGER]
fine  [012.50]
fine  [000.00]
count [456]
count [004]
no more input
code  [      ]
code  [      ]

The first line is padded with spaces, the second is cut to six characters, 12.5 is parsed as 12.5, abc becomes zero, 4567 lands in a three-digit field as 456 (the leading digits, not the low-order ones that a MOVE would keep), -4 loses its sign in the unsigned field, and the last ACCEPT meets end of input, takes the ON EXCEPTION branch and leaves spaces. With input that ends after one line (printf 'AB\n' | ./accept2), every later field is cleared:

code  [AB    ]
code  [      ]
fine  [000.00]
fine  [000.00]
count [000]
count [000]
no more input
code  [      ]
code  [      ]

Never assume that ACCEPT validated anything. Read into an alphanumeric item and test it with the class conditions (IS NUMERIC) before moving it to a numeric field; Conditions, IF and EVALUATE covers them and Error Handling and Declaratives covers the conditional phrases.

The console on z/OS

On z/OS, ACCEPT ... FROM CONSOLE is an operator interaction. The system issues a message code followed by the text AWAITING REPLY, the program is suspended, and the operator’s reply is moved to the receiving item left-justified. The statement ends when nothing is entered (the item keeps its old value), when the item is full, or when fewer than 114 characters were entered. DISPLAY ... UPON CONSOLE writes to the job log and, under TSO, to the terminal. These are for operator messages and are not a user interface; a production batch job reads its parameters from SYSIN and PARM, and an online user talks to CICS.

Command line and environment variables (GnuCOBOL)

GnuCOBOL gives access to the process’s arguments and environment through special device names. ACCEPT n FROM ARGUMENT-NUMBER returns the number of arguments; DISPLAY k UPON ARGUMENT-NUMBER chooses which one the next ACCEPT x FROM ARGUMENT-VALUE returns; ACCEPT x FROM COMMAND-LINE returns all arguments as one string. Environment variables are read with ACCEPT x FROM ENVIRONMENT "NAME", or in two steps with DISPLAY "NAME" UPON ENVIRONMENT-NAME followed by ACCEPT x FROM ENVIRONMENT-VALUE, and set with DISPLAY "NAME" UPON ENVIRONMENT-NAME followed by DISPLAY "value" UPON ENVIRONMENT-VALUE. ON EXCEPTION detects a variable that does not exist. The program below prints its arguments and reads two variables.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. ARGS1.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-ARG-COUNT        PIC 9(2).
       01  WS-ARG-NO           PIC 9(2).
       01  WS-ARG              PIC X(20).
       01  WS-COMMAND-LINE     PIC X(60).
       01  WS-RUN-DATE         PIC X(8) VALUE SPACES.
       01  WS-LIBRARY          PIC X(20) VALUE SPACES.
       PROCEDURE DIVISION.
       MAIN-PARA.
           ACCEPT WS-ARG-COUNT FROM ARGUMENT-NUMBER
           DISPLAY "Arguments: " WS-ARG-COUNT
           PERFORM VARYING WS-ARG-NO FROM 1 BY 1
                   UNTIL WS-ARG-NO > WS-ARG-COUNT
              DISPLAY WS-ARG-NO UPON ARGUMENT-NUMBER
              ACCEPT WS-ARG FROM ARGUMENT-VALUE
              DISPLAY "  argument " WS-ARG-NO " = ["
                 FUNCTION TRIM(WS-ARG) "]"
           END-PERFORM
           ACCEPT WS-COMMAND-LINE FROM COMMAND-LINE
           DISPLAY "Command line: [" FUNCTION TRIM(WS-COMMAND-LINE) "]"
           DISPLAY "CIRC_RUN_DATE" UPON ENVIRONMENT-NAME
           ACCEPT WS-RUN-DATE FROM ENVIRONMENT-VALUE
              ON EXCEPTION
                 DISPLAY "CIRC_RUN_DATE is not set" END-DISPLAY
              NOT ON EXCEPTION DISPLAY "Run date: " WS-RUN-DATE
           END-ACCEPT
           ACCEPT WS-LIBRARY FROM ENVIRONMENT "CIRC_LIBRARY"
              ON EXCEPTION
                 DISPLAY "CIRC_LIBRARY is not set" END-DISPLAY
              NOT ON EXCEPTION
                 DISPLAY "Library: " FUNCTION TRIM(WS-LIBRARY)
           END-ACCEPT
           DISPLAY "CIRC_LIBRARY" UPON ENVIRONMENT-NAME
           DISPLAY "Central Branch" UPON ENVIRONMENT-VALUE
           ACCEPT WS-LIBRARY FROM ENVIRONMENT "CIRC_LIBRARY"
           DISPLAY "Library now: " FUNCTION TRIM(WS-LIBRARY)
           GOBACK.

Run as ./args1 20261020 "A B" extra with neither variable set:

Arguments: 03
  argument 01 = [20261020]
  argument 02 = [A B]
  argument 03 = [extra]
Command line: [20261020 A B extra]
CIRC_RUN_DATE is not set
CIRC_LIBRARY is not set
Library now: Central Branch

Run with CIRC_RUN_DATE=20261020 CIRC_LIBRARY="North Branch" ./args1 and no arguments:

Arguments: 00
Command line: []
Run date: 20261020
Library: North Branch
Library now: Central Branch

The last line shows that DISPLAY ... UPON ENVIRONMENT-VALUE replaced the variable for the rest of the run. The change is visible to child processes started with CALL "SYSTEM" but not to the shell that started the program. The shell, not COBOL, expands wildcards in the arguments, so quote any argument that contains *.

Compiling the same program with -std=ibm works, because GnuCOBOL keeps these devices in that dialect, but -std=ibm-strict and -std=cobol85 reject them:

args1.cob: in paragraph 'MAIN-PARA':
args1.cob:13: error: unknown device 'ARGUMENT-NUMBER'; it may exist in another dialect
   13 >            ACCEPT WS-ARG-COUNT FROM ARGUMENT-NUMBER

A dangling NOT ON EXCEPTION

DISPLAY has its own ON EXCEPTION and NOT ON EXCEPTION phrases in GnuCOBOL. A NOT ON EXCEPTION written after a DISPLAY that sits inside the ON EXCEPTION of an ACCEPT therefore belongs to the DISPLAY, not to the ACCEPT. The following program is deliberately wrong and compiles without a warning:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. DANGLE1.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-LIBRARY          PIC X(20) VALUE SPACES.
       PROCEDURE DIVISION.
       MAIN-PARA.
      *    Deliberately wrong: NOT ON EXCEPTION binds to the DISPLAY.
           ACCEPT WS-LIBRARY FROM ENVIRONMENT "CIRC_LIBRARY"
              ON EXCEPTION DISPLAY "CIRC_LIBRARY is not set"
              NOT ON EXCEPTION
                 DISPLAY "Library: " FUNCTION TRIM(WS-LIBRARY)
           END-ACCEPT
           GOBACK.

With the variable not set it prints both branches, and with it set (CIRC_LIBRARY=North ./dangle1) it prints nothing at all, although the ACCEPT succeeded:

CIRC_LIBRARY is not set
Library:

Terminate the inner statement with END-DISPLAY (as args1.cob does) or use a separate paragraph for the exception branch.

Batch on z/OS: SYSIN, SYSOUT and PARM

A batch program on z/OS gets its small inputs from three places: the PARM string on the EXEC statement, the in-stream SYSIN data set, and the environment of the step. Its console-style output goes to the data set named by the SYSOUT ddname, or by the OUTDD compiler option if that was set. The job below runs the nightly circulation program with the run date as PARM and a control card in SYSIN; the JCL is covered in JCL for COBOL Programmers and the options in Compiling, Linking and Language Environment.

//CIRCNITE JOB (ACCT),'CIRC NIGHTLY',CLASS=A,MSGCLASS=X
//RUN010   EXEC PGM=CIRC010,PARM='20261020/'
//STEPLIB  DD DISP=SHR,DSN=USERID.CIRC.LOADLIB
//SYSIN    DD *
LIMIT 006
/*
//SYSOUT   DD SYSOUT=*
//CEEDUMP  DD SYSOUT=*

This JCL is z/OS only (z/OS; not run here); it follows the shape of the SYSIN, SYSOUT and PARM examples in the IBM Programming Guide. The trailing slash separates the program argument from the Language Environment run-time options; IBM’s own example passes '95/' and the program receives parm-len=002. The parameter is an area that starts with a two-byte binary length followed by the characters, so the program describes it in the LINKAGE SECTION and names it in PROCEDURE DIVISION USING:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. CIRC010.
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       SPECIAL-NAMES.
           SYSIN IS CONTROL-CARDS
           SYSOUT IS REPORT-LINE
           CONSOLE IS OPERATOR.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-CARD             PIC X(80).
       01  WS-RUN-DATE         PIC X(8).
       01  WS-LOAN-LIMIT       PIC 9(3) VALUE 4.
       LINKAGE SECTION.
       01  OS-PARM.
           05  PARM-LEN        PIC S9(4) COMP.
           05  PARM-DATA       PIC X(100).
       PROCEDURE DIVISION USING OS-PARM.
       MAIN-PARA.
           IF PARM-LEN NOT = 8
              DISPLAY "CIRC010: PARM must be a yyyymmdd run date"
                 UPON OPERATOR
              MOVE 16 TO RETURN-CODE
              GOBACK
           END-IF
           MOVE PARM-DATA(1:PARM-LEN) TO WS-RUN-DATE
           ACCEPT WS-CARD FROM CONTROL-CARDS
           IF WS-CARD(1:6) = "LIMIT " AND WS-CARD(7:3) IS NUMERIC
              MOVE WS-CARD(7:3) TO WS-LOAN-LIMIT
           END-IF
           DISPLAY "Circulation run " WS-RUN-DATE UPON REPORT-LINE
           DISPLAY "Loan limit per member: " WS-LOAN-LIMIT
              UPON REPORT-LINE
           GOBACK.

Enterprise COBOL passes the PARM as a halfword length followed by the string, which is exactly the shape that OS-PARM describes (use a two-byte binary item such as PIC S9(4) COMP, as IBM’s own example does). The program checks the length before it uses the data, because PARM may be absent or shorter than expected and the PARM-DATA bytes beyond PARM-LEN are not valid. It reads the control card with ACCEPT ... FROM SYSIN into an 80-byte item, the length of a card image, and writes with DISPLAY ... UPON SYSOUT. Anything wrong sets RETURN-CODE for the COND and IF tests of the following job steps.

The program syntax and logic can be run without a mainframe if a small driver builds the same two-byte-length parameter and calls the program, so the following driver does that. It is not how the job runs on z/OS (the system builds the parameter there), and the compile uses -std=ibm so that PIC S9(4) COMP is two bytes, as on z/OS.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. PARMDRV.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-PARM.
           05  WS-PARM-LEN     PIC S9(4) COMP.
           05  WS-PARM-DATA    PIC X(100).
       PROCEDURE DIVISION.
       MAIN-PARA.
           MOVE 8 TO WS-PARM-LEN
           MOVE "20261020" TO WS-PARM-DATA
           CALL "CIRC010" USING WS-PARM
           DISPLAY "Return code: " RETURN-CODE
           MOVE 5 TO WS-PARM-LEN
           MOVE "20261" TO WS-PARM-DATA
           CALL "CIRC010" USING WS-PARM
           DISPLAY "Return code: " RETURN-CODE
           STOP RUN.

Compiled with cobc -m -Wall -std=ibm circ010.cob, cobc -x -Wall -std=ibm parmdrv.cob and run with printf 'LIMIT 006\n' | ./parmdrv, with no warnings, the output is:

Circulation run 20261020
Loan limit per member: 006
Return code: +000000000
CIRC010: PARM must be a yyyymmdd run date
Return code: +000000016

The first call received an eight-character date and the card LIMIT 006; the second received a five-character string and ended with return code 16. With the card LIMIT 6 (printf 'LIMIT 6\n' | ./parmdrv) the numeric test on columns 7 to 9 fails and the default limit 004 is kept:

Circulation run 20261020
Loan limit per member: 004
Return code: +000000000
CIRC010: PARM must be a yyyymmdd run date
Return code: +000000016

Other ways to read the PARM are the Language Environment services CEE3PRM (a string up to 80 characters) and CEE3PR2 (string and its length). Under CBLOPTS(ON), the default, the string is program_arguments/runtime_options; for AMODE 64 CBLOPTS is not supported and the order is reversed. A program started from the z/OS UNIX shell, exec() or spawn() receives three parameters instead: an argument count, an array of pointers to the argument lengths and an array of pointers to the null-terminated arguments, the first of which is the name of the program.

SYSIN, SYSOUT and the other ddnames

ddname or name Used by Notes

SYSIN, SYSIPT

ACCEPT

The system logical input unit. If the ddname is not defined and the program runs under z/OS UNIX, stdin is the source; if it is not defined elsewhere the ACCEPT fails.

SYSOUT, SYSLIST, SYSLST

DISPLAY

The system logical output unit. Defaults to the ddname in the OUTDD compiler option; if that is not allocated and the program does not run under z/OS UNIX, a SYSOUT=* data set is allocated.

SYSPUNCH, SYSPCH

DISPLAY

The punch device; a z/OS UNIX file can be named with PATH= on the DD statement.

CONSOLE

ACCEPT and DISPLAY

Operator console (see above).

C01 to C12, CSP, S01 to S05, AFP-5A

WRITE ADVANCING

Printer and punch control names; not used with DISPLAY or ACCEPT.

Do not use SYSOUT as the ddname or environment variable name in a SELECT clause for a file, because DISPLAY output is directed to it. If the OUTDD ddname and the Language Environment MSGFILE option name the same ddname, both DISPLAY output and the run-time diagnostics go to the same data set. The names are bound in SPECIAL-NAMES, for example SYSIN IS CONTROL-CARDS.

Extended ACCEPT and DISPLAY for screens (GnuCOBOL)

GnuCOBOL adds statement forms for a text terminal that do not need a SCREEN SECTION: DISPLAY item AT LINE n COLUMN m and ACCEPT item AT LINE n COLUMN m, with a WITH list of attributes (BACKGROUND-COLOR, FOREGROUND-COLOR, HIGHLIGHT, LOWLIGHT, REVERSE-VIDEO, UNDERLINE, BLINK, BELL, BLANK LINE or SCREEN, ERASE EOL or EOS, AUTO, SECURE, REQUIRED, FULL, UPDATE, SIZE, TIMEOUT AFTER n) and ON EXCEPTION for keys that end the input. DISPLAY SPACE clears from the cursor to the end of the screen. ACCEPT OMITTED waits for a key and sets the status without storing data. The key that ended the input is returned in the CRT STATUS data item.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. SCREEN2.
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       SPECIAL-NAMES.
           CRT STATUS IS WS-KEY.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
           COPY screenio.
       01  WS-KEY              PIC 9(4) VALUE 0.
       01  WS-MEMBER-ID        PIC 9(6) VALUE 0.
       PROCEDURE DIVISION.
       MAIN-PARA.
           DISPLAY SPACE
           DISPLAY "Member id:" AT LINE 2 COLUMN 2
           ACCEPT WS-MEMBER-ID AT LINE 2 COLUMN 13
              WITH TIMEOUT AFTER 1 REVERSE-VIDEO
              ON EXCEPTION
                 EVALUATE WS-KEY
                    WHEN COB-SCR-F3
                       DISPLAY "F3 pressed" UPON SYSERR
                    WHEN COB-SCR-ESC
                       DISPLAY "Escape pressed" UPON SYSERR
                    WHEN OTHER
                       DISPLAY "Exception key " WS-KEY UPON SYSERR
                 END-EVALUATE
              NOT ON EXCEPTION
                 DISPLAY "Entered " WS-MEMBER-ID UPON SYSERR
           END-ACCEPT
           GOBACK.

This program needs a real terminal (it uses curses), so it was compiled with cobc -x -Wall (no warnings) and then run under a pseudo-terminal (script) with TERM=xterm and scripted keystrokes, writing its result to standard error. Doing nothing for one second gives the time-out status, typing 123456 and Enter takes the normal path, and the F3 key (the xterm sequence ESC O R) ends the input with its function-key code:

Exception key 8001
Entered 123456
F3 pressed

CRT STATUS IS WS-KEY in SPECIAL-NAMES names a four-digit data item that receives one of the codes below after every screen ACCEPT. If the clause is not written, GnuCOBOL uses an implicit COB-CRT-STATUS item. The copybook screenio.cpy, supplied with the compiler, defines names for them (COB-SCR-F3 and so on) and for the eight colors (COB-COLOR-BLACK to COB-COLOR-WHITE); it is licensed under the GPL and is included with COPY screenio. rather than copied.

CRT STATUS Meaning

0000

Enter was pressed

1001 to 1064

Function keys F1 to F64

2001, 2002

Page Up, Page Down

2003, 2004

Up arrow, Down arrow

2005

Esc

2006

Print Screen

2007, 2008

Tab, Back Tab

2009, 2010

Left, Right (with AUTO-SKIP)

2011 to 2015

Insert, Delete, Backspace, Home, End (only on ACCEPT OMITTED)

2040 to 2095

Mouse and wheel events, if mouse handling was enabled with COB_MOUSE_FLAGS

8000

No field

8001

Time-out

9000

Fatal

9001

Maximum field

Page Up and Page Down end an ACCEPT only when the run-time variable COB_SCREEN_EXCEPTIONS has a non-blank value, and Esc also needs COB_SCREEN_ESC. COB_TIMEOUT_SCALE sets the unit of the TIMEOUT value. When a program shows a screen and then stops without an ACCEPT, COB_EXIT_WAIT (default on) makes the run-time wait for a key so that the screen is not wiped at once.

SCREEN SECTION

The SCREEN SECTION is the last section of the Data Division. It describes whole screens as a hierarchy of screen items, and a single DISPLAY screen-name paints the screen while a single ACCEPT screen-name reads every input field on it. COBOL 2002 introduced it, and GnuCOBOL implements it for text terminals only (no graphics).

A screen item has a level number, an optional name, and clauses:

Clause Effect

LINE n, COLUMN n, LINE PLUS n, COLUMN PLUS n

Absolute or relative position. Without them an item follows the previous one.

VALUE "text"

A literal shown on the screen.

FROM item

Shows the contents of a data item (output only).

TO item

Reads into a data item (input only).

USING item

Shows the item and reads back into it (input and output).

PIC picture

Required for items that show or read data.

BLANK SCREEN, BLANK LINE, ERASE EOL, ERASE EOS

Clears all or part of the screen.

HIGHLIGHT, LOWLIGHT, REVERSE-VIDEO, UNDERLINE, OVERLINE, LEFTLINE, BLINK, BELL (or BEEP)

Video attributes and the terminal bell.

FOREGROUND-COLOR n, BACKGROUND-COLOR n

Colors, using the numbers in screenio.cpy.

AUTO (AUTO-SKIP, AUTOTERMINATE)

The field ends the input when full, without Enter.

REQUIRED (EMPTY-CHECK), FULL (LENGTH-CHECK)

The field must not be left empty, or must be filled completely.

SECURE (NO-ECHO)

Typed characters are not shown, as for a password.

PROMPT CHARACTER IS x

The character shown in an empty input field.

JUSTIFIED RIGHT, BLANK WHEN ZERO, SIGN

Edit the shown value like the data description clauses of the same names.

OCCURS n TIMES

A repeated screen item.

The synonyms in parentheses are interchangeable in GnuCOBOL. Level 01 constants, 66, 78 and 88 are also allowed in this section. The -fscreen-section-rules= compiler option selects whether the clause rules follow the GnuCOBOL (gc, the default), std, mf, acu, rm or xopen behaviour.

The program below is a checkout form for the Circulation scenario. CHECKOUT-SCREEN clears the screen and has two input fields (USING), one output field (FROM) that shows a message, and literals. The main loop shows the screen, reads it, and stops when CRT STATUS reports F3.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. SCREEN1.
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       SPECIAL-NAMES.
           CRT STATUS IS WS-KEY.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
           COPY screenio.
       01  WS-KEY              PIC 9(4) VALUE 0.
       01  WS-MEMBER-ID        PIC 9(6) VALUE 0.
       01  WS-BOOK-ID          PIC 9(6) VALUE 0.
       01  WS-MESSAGE          PIC X(40) VALUE SPACES.
       SCREEN SECTION.
       01  CHECKOUT-SCREEN.
           05  BLANK SCREEN BACKGROUND-COLOR COB-COLOR-BLACK
                            FOREGROUND-COLOR COB-COLOR-WHITE.
           05  LINE 1 COLUMN 2 VALUE "CIRCULATION - CHECKOUT"
                            HIGHLIGHT.
           05  LINE 3 COLUMN 2 VALUE "Member id:".
           05  LINE 3 COLUMN 14 PIC 9(6) USING WS-MEMBER-ID
                            REVERSE-VIDEO REQUIRED.
           05  LINE 4 COLUMN 2 VALUE "Book id:".
           05  LINE 4 COLUMN 14 PIC 9(6) USING WS-BOOK-ID
                            REVERSE-VIDEO AUTO.
           05  LINE 6 COLUMN 2 PIC X(40) FROM WS-MESSAGE
                            FOREGROUND-COLOR COB-COLOR-RED.
           05  LINE 8 COLUMN 2 VALUE "Enter = post, F3 = quit".
       PROCEDURE DIVISION.
       MAIN-PARA.
           PERFORM UNTIL WS-KEY = COB-SCR-F3
              DISPLAY CHECKOUT-SCREEN
              ACCEPT CHECKOUT-SCREEN
              EVALUATE TRUE
                 WHEN WS-KEY = COB-SCR-F3
                    CONTINUE
                 WHEN WS-MEMBER-ID = 102
                    MOVE "Member 102 is suspended" TO WS-MESSAGE
                 WHEN OTHER
                    MOVE "Checkout posted" TO WS-MESSAGE
              END-EVALUATE
           END-PERFORM
           GOBACK.

The program compiled with cobc -x -Wall with no warnings. It cannot run in a pipe: with standard input at end of file each ACCEPT returns at once, F3 never arrives, and the loop does not end (the container running it had to be stopped). It was therefore run under a pseudo-terminal (TERM=xterm, 10 rows by 40 columns) with the keystrokes 000102, Enter, Enter and F3. Because the captured output is a stream of terminal escape sequences, the final screen below was reconstructed from it by hand: Member id 000102 is highlighted in reverse video, and the red message Member 102 is suspended was set by the program after the first Enter. Pressing Enter on the empty required Member id field instead made the terminal beep and kept the cursor on the field.

 CIRCULATION - CHECKOUT

 Member id:  000102
 Book id:    000000

 Member 102 is suspended

 Enter = post, F3 = quit

Portability

Compiling screen1.cob with -std=ibm gives no diagnostic, because GnuCOBOL does not restrict its extensions in that dialect, but Enterprise COBOL for z/OS has no SCREEN SECTION, so the program is not portable to z/OS. In the stricter dialects the first failure is the CRT STATUS clause:

screen1.cob:6: error: invalid system-name 'CRT'
    6 >            CRT STATUS IS WS-KEY.

(That is the result of -std=ibm-strict, and -std=cobol85 gives the same message. Under -std=cobol2014 the first error is in screenio.cpy, whose level 78 constants "do not conform to COBOL 2014".) A text screen on z/OS means CICS with a BMS map and the SEND MAP and RECEIVE MAP commands, described in CICS Online Programming. Micro Focus and ACUCOBOL-GT have similar screen forms (hence the mf and acu choices of -fscreen-section-rules), but the clauses differ in detail.

Pitfalls

The messages in the table were produced by GnuCOBOL 3.2.0.

Mistake Symptom Fix

An ACCEPT loop that waits for a key, run with standard input redirected

No error; the loop spins because each ACCEPT returns at once (as screen1 did)

Test for end of input or an exception key, and run screen programs on a terminal

COPY SCREENIO. on a case-sensitive file system

error: SCREENIO: No such file or directory, then 'COB-COLOR-BLACK' is not defined and similar

The copybook file is screenio.cpy; write COPY screenio.

A source line that runs past column 72

error: 'WS-AR' is not defined, then syntax error, unexpected Literal, expecting LEADING or TRAILING

Keep text in columns 8 to 72; see Reference Format: Fixed and Free

NOT ON EXCEPTION after a nested DISPLAY

Wrong branch runs; no diagnostic (shown above)

End the inner statement with END-DISPLAY

Numeric ACCEPT with bad text

The item silently becomes zero

Accept into an alphanumeric item and test IS NUMERIC

Longer input than the receiving item

GnuCOBOL cuts the line; a four-digit number in a three-digit field keeps the leading digits

Size the item for the longest valid input and check the length

Parsing the text of a DISPLAY of a signed packed or binary item

Different text under -std=ibm, and on z/OS an overpunched sign

Move to a numeric-edited field first

References