GnuCOBOL Programmer’s Guide Guide 2.2 Final [7Sept2017]

Table of Contents

5th Edition, Update 1 - Sept 2017 for v2.2 Final.

  1. 09/09 Fix and cleared, Bug #422.
  2. 09/09 Change around SPECIAL-NAMES and REPOSITORY as wrong order, Bug #424.
  3. 10/09 Added system library elements CBL_GC_ FORK, GETOPT*, HOSTED*, NANOSLEEP*, PRINTABLE (Replaces legacy C$PRINTABLE) AND WAITPID (Replaces legacy C$WAITPID). Note legacy names still supported at least for now but may well be removed so suggest replace names likewise replace CBL_OC_xxx* with CBL_GC_xxx).
  4. 11/09 Added new note in chap. 1 - Introduction regarding non avail of RWCS and ref to 1.3.13.
  5. Renamed usage of CBL_OC to CBL_GC for CBL_GC library routines within CBL_GC sections.
  6. Added new entries as 8.1.3 and moved up following 8.1 entries. Likewise for main menu.
  7. Added new for 8.2.3 showing runtime.cfg and updated with current default.conf at same.
  8. Adjust 4.1.3 & 4.1.4 as not set up in index of 1 & 4 in right order.
  9. Checked and changed menus for incorrect or missing numbering.
  10. 14/10 Bug #447 fixed (CDF Replacing trailing == missing.
  11. 20/10 Bug #450 Removed example one and refs to COMP-5, added note for the three usage types trunc applies to and amended the performance test example with resulting figures.
  12. 01/11 Added Appendix E for changes since 2009 thanks to Edward Hart (see his grammar document).

1. Introduction

The original principal developers of GnuCOBOL were Keisuke Nishida and Roger While. Since then many others of the GnuCobol community are directly involved in it’s development at any one time.

This document is intended to serve as a full-function reference and user’s guide suitable for both those readers learning COBOL for the first time as usage as a training tool, as well as those already familiar with some dialect of the COBOL language.

A separate manual exists that just contains the details of the GNUCobol implementation which is designed strictly for experienced Cobol programmers taken from this guide. This document (GnuCobol Quick Reference) does NOT contain any training subject matter.

Caution. Although this document is for version 2.2 of the compiler, it also includes a description of the functions of the RWCS (Report Writer module) which is not included in the compiler version 2.2. Please see availability notes on this at 1.3.13.



1.1. Additional Reference Sources

If you like to hold a book in your hands, I strongly recommend "Murach’s Structured COBOL", by Mike Murach, Anne Prince and Raul Menendez (2000) - ISBN 9781890774059. Mike Murach and his various writing partners have been writing outstanding COBOL textbooks for decades, and this text is no exception. It’s an excellent book for those familiar with the concepts of programming in other languages, but unfamiliar with COBOL.

Would you prefer a web-based tutorial? Try the University of Limerick (Ireland) COBOL web site - ‘http://www.csis.ul.ie/cobol/’.



1.2. Introducing COBOL

COBOL, first introduced to the programming public in 1959, was the very first programming language to become standardized (in 1960). This meant that a standard-compliant COBOL program written on computer "A" made by company "B" would be able to be compiled and executed on computer "X" made by company "Y" with very few, if any, changes. This may not seem like such a big deal today, but it was a radical departure from all programming languages that came before it and even many that came after it.

The name COBOL actually says it all — COBOL is an acronym that stands for "(CO)mmon (B)usiness (O)riented (L)anguage". Note the fact that the word "common" comes before all others. The word "business" is a close second. Therein lies the key to Cobol’s success.



1.2.1. Why YOU Should Learn COBOL

  1. They conform to the principles of Object-Oriented Programming (OOP). This is desired for one major reason — it facilitates "code re-usability", thus improving the productivity of programmers by allowing them to re-use previously written (and debugged) code in new applications. For one reason or another, COBOL is perceived as being weak in this regard. It isn’t (especially today), as we’ll see in the next section, but perception is important.
  2. Those languages aren’t limited to mainframe computers, as COBOL is perceived to be. Some, like .NET and Ruby, aren’t even available on mainframes. The "modern" programming languages were designed and intended for use on the full variety of computer platforms, from shirt-pocket computers (i.e. smart phones) up to the most massive of supercomputers.
  3. There are several excellent commercially available COBOL implementations available for non-mainframe systems (Micro Focus COBOL, AccuCOBOL, NetCOBOL and Elastic COBOL, just to name a few), including Windows and UNIX/Linux systems. These aren’t cheap, however.
  4. Universities love the "Modern" languages. In the U.S., 73% of colleges lack even one COBOL course on their curricula. COBOL, it appears, is no longer "cool" enough for students to fill a classroom.

Just because COBOL doesn’t traditionally support objects, classes, and the like doesn’t mean that its "procedural" approach to computing isn’t valuable — after all, it runs 70% of the worlds business transactions, and does so:


Today’s IT managers and business leaders are faced with a challenging dilemma — how do you maintain the enormous COBOL code base that is still running their businesses when academia has all but abandoned the language they need their people to use to keep the wheels rolling? The problem is compounded by the fact that those programmers that are skilled in COBOL are retiring and taking their knowledge with them. In some markets, this appears to be having an inflationary effect on the cost of resources (COBOL programmers) whose supply is becoming smaller and smaller. The pressure to update applications to make use of more up-to-date graphical user interfaces is also perceived as a reason to abandon COBOL in favour of GUI-friendly languages such as Java.

Businesses are addressing the COBOL challenge in different ways:

  1. By undertaking so-called "modernization projects", where existing applications are either rewritten in "modern" languages or replaced outright with purchased packages. Most of these businesses are using such activities as an excuse to abandon "expensive" mainframes in favour of (presumably) less-expensive "open systems" (mid frame/server) solutions.
  2. Many times these businesses are finding the cost of the system/networking engineering, operational management and monitoring and risk management (i.e. disaster recovery) infrastructures necessary to support truly mission-critical applications to be so high that the "less-expensive" solution really isn’t; in these cases the mainframe may remain the best option, thus leaving COBOL in play and businesses seeking another solution for at least part of their application base.
  3. Training their own COBOL programmers. Since colleges, universities and technical schools have lost interest in doing so, many businesses have undertaken the task of "growing their own" new crop of COBOL programmers. Fear of being pigeon-holed into a niche technology is a factor inhibiting many of today’s programmers from willingly volunteering for such training.
  4. By moving the user-interface onto the desktop; such efforts involve running modern-language front-end clients on user desktops (or laptops or smart phones, etc.) with COBOL programs providing server functionality on mainframe or midframe platforms, providing all the database and file "heavy lifting" on the back-end. Solutions like this provide users with the user-interfaces they want/need while still leveraging Cobol’s strengths on (possibly) downsized legacy mainframe or midframe systems.

It’s probably a true that an IT professional can no longer afford to allow COBOL to be the only wrench in their toolbox, but with a massive code base still in production now and for the foreseeable future, adding COBOL to a multi-lingual curriculum vitae (CV) and/or resume (yes — they ARE different) is not a bad thing at all. Knowing COBOL as well as the language du-jour will make you the smartest person in the room when the discussion of migrating the current "legacy" environment to a "modern" implementation comes around.

You’ll find COBOL an easy language to learn and a FAR EASIER language to master than many of the "modern" languages.

The whole reason you’re reading this is that you’ve discovered GnuCOBOL — another implementation of COBOL in addition to those mentioned earlier. The distinguishing characteristic of GnuCOBOL versus those others is that GnuCOBOL is FREE open-source and therefore FREE to obtain and use. It is community-enhanced and community-supported. Later in this document (see So What is GnuCOBOL?), you’ll begin to learn more about this COBOL implementation’s capabilities.



1.2.2. Programmer Productivity

The amount of programming necessary to accomplish a given task — including rework needed by any errors found during testing (testing is sometimes jokingly defined as: "that time during which an application is actually in production, allowing users to discover the problems") is the measure of programmer productivity. Anything that reduces that effort will therefore reduce the time spent in such activities therefore reducing the expense of same. When the expense of programming is reduced, programmer productivity is increased.

Sometimes the quest for improved programmer productivity (and therefore reduced programming expense) has taken the form of introducing new features in programming languages, or even new languages altogether. Sometimes it has resulted in new ways of using the existing languages.

While many technological and procedural developments have made evolutionary improvements to programmer productivity, each of the following three events has been responsible for revolutionary improvements:


While GnuCOBOL supports few of the OOP programming constructs defined by the COBOL2002 and COBOL20xx standards, it supports every aspect of the ANSI 85 standard and therefore fully meets the needs of points #1 and #2, above. With it’s supported feature set (see So What is GnuCOBOL?), it provides significant programmer productivity capabilities.



1.3. So What is GnuCOBOL?

The MinGW approach is a personal favourite with the author of this manual because it creates a GnuCOBOL compiler and runtime library that require only a single MinGW DLL to be available for the GnuCOBOL compiler, runtime library and user programs. That DLL is freely distributable under the terms of the GNU General Public License. A MinGW build of GnuCOBOL fits easily on and runs from a 128MB flash drive with no need to install any software onto the Windows computer that will be using it. Some functionality of the language, dealing with the sharing of files between concurrently executing GnuCOBOL programs and record locking on certain types of files, is sacrificed however as the underlying operating system routines needed to implement them aren’t available to Windows and aren’t provided by MinGW. The current version for MinGW is available at the download link along with various other platforms at the GnuCobol download website (https://sourceforge.net/projects/open-cobol/files/gnu-cobol/2.0/).

GnuCOBOL has also been built as a truly native Windows application utilizing Microsoft’s freely-downloadable Visual Studio Express package to provide the C compiler and linker/loader. This approach does not lend itself well to a "portable" distribution.

The GnuCOBOL compiler generates C code from your COBOL programs; that C code is then automatically compiled and linked using your system’s C compiler (typically, but not limited to, "gcc").

GnuCOBOL fully supports much of the ANSI 85 standard for COBOL (the only major exclusion is the Communications Module) and also supports some of the components of the COBOL2002 standard, such as the "SCREEN SECTION" (see SCREEN SECTION), table-based "SORT" (see Table SORT) and user-defined functions.



1.3.1. Language Reserved Words

The GnuCOBOL language specification defines over 900 ’Reserved Words

Programmers may use a reserved word as part of a word they are creating themselves, but may not create their own word as an exact duplicate (without regard to case) of a COBOL reserved word. Note that a reserved word includes all classes, such as intrinsic functions, mnemonics names, system routines and reserved words.

See Appendix B - Reserved Word List, for a complete list of GnuCOBOL reserved words for the current release.



1.3.2. User-Defined Words

User-defined words may be composed from the characters "A" through "Z" (upper- and/or lower-case), "0" through "9", dash ("-")

Other programming language provide the programmer with a similar capability of creating their own words (names) for parts of a program; COBOL is somewhat unusual when compared to other languages in that user-defined words may start with a digit.

With the exception of logic procedure names, which may consist entirely of nothing but digits, user-defined words must contain at least one letter.



1.3.3. Case Insensitivity

The only time the case used does matter is within quoted character strings, where character values will be exactly as coded.

By convention throughout this document, COBOL reserved words will be shown entirely in UPPER-CASE while those words that were created by a programmer will be represented by tokens in mixed or lower case.

This isn’t a bad practice to use in actual programs, as it leads to programs where it is much easier to distinguish reserved words from user-defined ones!



1.3.4. Readability of Programs

Here are two different "Hello World" applications — one written in Java and the second in GnuCOBOL. First, the Java version:

    Class HelloWorld {
        public static void main(String[] args) {
            System.out.println("Hello World!");
        }
    }

And here is the same program, written in GnuCOBOL:

    IDENTIFICATION DIVISION.
    PROGRAM-ID. HelloWorld.
    PROCEDURE DIVISION.
        DISPLAY "Hello World!".

Both of the above programs could have been written on a single line, if desired, and both languages allow a programmer to use (or not use) indentation as they see fit to improve program readability. Sounds like a tie so far.

Let’s look at how much more "wordy" COBOL is than Java. Count the characters in the two programs. The Java program has 95 (not counting carriage returns and any indentation). The COBOL program has 89 (again, not counting carriage returns and indentation)! Technically, it could have been only 65 because the "IDENTIFICATION DIVISION." header is actually optional. Clearly, "Hello World" doesn’t look any more concise in Java than it does in COBOL.

Let’s look at a different problem. Surely a program that asks a user to input a positive integer, generates the sum of all positive integers from 1 to that number and then prints the result will be MUCH shorter and MUCH easier to understand when coded in Java than in COBOL, right?

You can be the judge. First, the Java version:

    import java.util.Scanner;
    public class sumofintegers {
        public static void main(String[] arg) {
            System.out.println("Enter a positive integer");
            Scanner scan=new Scanner(System.in);
            int n=scan.nextInt();
            int sum=0;
            for (int i=1;i<=n;i++) {
                sum+=i;
            }
            System.out.println("The sum is "+sum);
        }
    }

And now for the COBOL version:

    IDENTIFICATION DIVISION.
    PROGRAM-ID. SumOfIntegers.
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    01 n   BINARY-LONG.
    01 i   BINARY-LONG.
    01 sum BINARY-LONG VALUE 0.
    PROCEDURE DIVISION.
    DISPLAY "Enter a positive integer"
    ACCEPT n
    PERFORM VARYING i FROM 1 BY 1 UNTIL i > n
        ADD i TO sum
    END-PERFORM
    DISPLAY "The sum is " sum.

My familiarity with COBOL may be prejudicing my opinion, but it doesn’t appear to me that the Java code is any simpler than the COBOL code. In case you’re interested in character counts, the Java code comes in at 278 (not counting indentation characters). The COBOL code is 298 (274 without the "IDENTIFICATION DIVISION." header).

Despite what you’ve seen here, the more complex the programming logic being implemented, the more concise the Java code will appear to be, even compared to 2002-standard COBOL. That conciseness comes with a price though — program code readability. Java (or C or C++ or C#) programs are generally intelligible only to trained programmers. COBOL programs can, however, be quite understandable by non-programmers. This is actually a side-effect of the "wordiness" of the language, where COBOL statements use natural English words to describe their actions. This inherent readability has come in handy many times throughout my career when I’ve had to learn obscure business (or legal) processes by reading the COBOL program code that supports them.

The "modern" languages, like Java, also have their own "boilerplate" infrastructure overhead that must be coded in order to write the logic that is necessary in the program. Take for example the "public static void main(String[] arg)" and "import java.util.Scanner;" statements. The critics tend to forget about this when they criticize COBOL for it’s structural "overhead".

When it first was developed, Cobol’s easily-readable syntax made it profoundly different from anything that had been seen before. For the first time, it was possible to specify logic in a manner that was — at least to some extent — comprehensible even to non-programmers. Take for example, the following code written in FORTRAN — a language developed only a year before COBOL:

    EXT = PRICE * IQTY
    INVTOT = INVTOT + EXT

With its original limitation on the length of variable names (one- to six-character names comprised of a letter followed by up to five letters and/or digits), it’s implicit rule that variable were automatically created as real (floating-point) unless their name started with a letter in the range I-N, and its use of algebraic notation to express actions being taken, FORTRAN wasn’t a particularly readable language, even for programmers. Compare this with the equivalent COBOL code:

    MULTIPLY price BY quantity GIVING extended-amount
    ADD extended-amount TO invoice-total

Clearly, even a non-programmer could at least conceptually understand what was going on! Over time, languages like FORTRAN evolved more robust variable names, and COBOL introduced a more formula-based syntactical capability for arithmetic operations, but FORTRAN was never as readable as COBOL.

Because of its inherent readability, I would MUCH rather be handed an assignment to make significant changes to a COBOL program about which I know nothing than to be asked to do the same with a C, C++, C# or Java program.

Those that argue that it is too boring / wasteful / time-consuming / insulting (pick one) to have to code a COBOL program "from scratch" are clearly ignorant of the following facts:



1.3.5. Divisions Organize Programs

Each division may consist of a variety of sections and each section consists of one or more paragraphs. A paragraph consists of sentences, each of which consists of one or more statements.

This hierarchical structure of program components standardizes the composition of all COBOL programs. Much of this manual describes the various divisions, sections, paragraphs and statements that may comprise any COBOL program.



1.3.6. Copybooks

Today’s current programming languages have a statement (usually, this statement is named "import", "include" or "#include") that performs this same function. What makes the COBOL copybook feature different than the "include" facility in newer languages, however, is the fact that the "COPY" statement can edit the imported source code as it is being copied. This capability makes copybook libraries extremely valuable to making code reusable.



1.3.7. Structured Data

COBOL introduced the concept of structured data. The principle of structured data in COBOL is based on the idea of being able to group related and contiguously-allocated data items together into a single aggregate data item, called a ’Group Item

A data item that isn’t itself formed from other data items is referred to in COBOL as an ’Elementary Item



1.3.8. Files

"ORGANIZATION LINE SEQUENTIAL"

These are files with the simplest of all internal structures. Their contents are structured simply as a series of identically- or differently-sized data records, each terminated by a special end-of-record delimiter character. An ASCII line-feed character (hexadecimal 0A) is the end-of-record delimiter character used by any UNIX or pseudo-UNIX (MinGW, Cygwin, OSX) GnuCOBOL build. A truly native Windows build would use a carriage-return, line-feed (hexadecimal 0D0A) sequence.

Records must be read from or written to these files in a purely sequential manner. The only way to read (or write) record number 100 would be to have read (or written) records number 1 through 99 first.

When the file is written to by a GnuCOBOL program, the delimiter sequence will be automatically appended to each data record as it is written to the file. A "WRITE" (see WRITE) to this type of file will be done as if a "BEFORE ADVANCING 1 LINE" clause were specified on the "WRITE", if no "ADVANCING" clause is coded.

When the file is read, the GnuCOBOL runtime system will strip the trailing delimiter sequence from each record. The data will be padded (on the right) with spaces if the data just read is shorter than the area described for data records in the program. If the data is too long, it will be truncated and the excess will be lost.

These files should not be defined to contain any exact binary data fields because the contents of those fields could inadvertently have the end-of-record sequence as part of their values — this would confuse the runtime system when reading the file, and it would interpret that value as an actual end-of-record sequence.

"LINE ADVANCING"

These are files with an internal structure similar to that of a line sequential file. These files are defined (without an explicit "ORGANIZATION" specification) using the "LINE ADVANCING" clause on their "SELECT" statement (see SELECT).

When this kind of file is written to by a GnuCOBOL program, an end-of-record delimiter sequence will be automatically added to each data record as it is written to the file. A "WRITE" to this type of file will be done as if an "AFTER ADVANCING 1 LINE" clause were specified on the "WRITE", if no "ADVANCING" clause is coded.

Like line sequential files, these files should not be defined to contain any exact binary data fields because the contents of those fields could inadvertently have the end-of-record sequence as part of their values — this would confuse the runtime system when reading the file, and it would interpret that value as an actual end-of-record sequence.

"ORGANIZATION SEQUENTIAL"

These files also have a simple internal structure. Their contents are structured simply as an arbitrarily-long sequence of data characters. This sequence of characters will be treated as a series of fixed-length records simply by logically splitting the sequence of characters up into fixed-length segments, each as long as the maximum record size defined in the program. There are no special end-of-record delimiter characters in the file and when the file is written to by a GnuCOBOL program, no delimiter sequence is appended to the data.

Records in this type of file are all the same physical length, except possibly for the very last record in the file, which may be shorter than the others. If variable-length logical records are defined to the program, the space occupied by each physical record in the file will occupy the space described by the longest record description in the program.

So, if a file contains 1275 characters of data, and a program defines the structure of that file as containing 100-character records, then the file contents will consist of twelve (12) 100-character records with a final record containing only 75 characters.

It would appear that it should be possible to locate and process any record in the file directly simply by calculating its starting character position based upon the program-defined record size. Even so, however, records must be still be read or written to these files in a purely sequential manner. The only way to read (or write) record number 100 would be to have read (or written) records number 1 through 99 first.

When the file is read, the data is transferred into the program exactly as it exists in the file. In the event that a short record is read as the very last record, that record will be padded (to the right) with spaces.

Care must be taken that programs reading such a file describe records whose length is exactly the same as that used by the program that created the file. For example, the following shows the contents of a "SEQUENTIAL" file created by a program that wrote five 6-character records to it. The "A", "B", … values reflect the records that were written to the file:

AAAAAABBBBBBCCCCCCDDDDDDEEEEEE

Now, assume that another program reads this file, but describes 10-character records rather than 6. Here are the records that program will read:

AAAAAABBBB
BBCCCCCCDD
DDDDEEEEEE

There may be times where this is exactly what you were looking for. More often than not, however, this is not desirable behaviour. Suggestion: use a copybook to describe the record layouts of any file; this guarantees that multiple programs accessing that file will "see" the same record sizes and layouts by coding a "COPY" statement (see COPY) to import the record layout(s) rather than hand-coding them.

These files can contain exact binary data fields. This is possible because — since there is no character sequence that constitutes an end-of-record delimiter — the contents of record fields are irrelevant to the reading process.

"ORGANIZATION RELATIVE"

The contents of these files consist of a series of fixed-length data records prefixed with a four-byte record header. The record header contains the length of the data, in bytes. The byte-count does not include the four-byte record header.

Records in this type of file are all the same physical length. If variable-length logical records are defined to the program, the space occupied by each physical record in the file will occupy the maximum possible space, and the logical record length field will contain the number of bytes of data in the record that are actually in use.

This file organization was defined to accommodate either sequential or random processing. With a "RELATIVE" file, it is possible to read or write record 100 directly, without having to have first read or written records 1-99. The GnuCOBOL runtime system uses the program-defined maximum record size to calculate a relative byte position in the file where the record header and data begin, and then transfers the necessary data to or from the program.

When the file is written by a GnuCOBOL program, no delimiter sequence is appended to the data, but a record-length field is added to the beginning of each physical record.

When the file is read, the data is transferred into the program exactly as it exists in the file.

Care must be taken that programs reading such a file describe records whose length is exactly the same as that used by the programs that created the file. It won’t end well if the GnuCOBOL runtime library interprets a four-byte ASCII character string as a record length when it transfers data from the file into the program!

Suggestion: use a copybook to describe the record layouts of any file; this guarantees that multiple programs accessing that file will "see" the same record sizes and layouts by coding a "COPY" statement (see COPY) to import the record layout(s) rather than hand-coding them.

These files can contain exact binary data fields. The contents of record fields are irrelevant to the reading process as there is no end-of-record delimiter.

"ORGANIZATION INDEXED"

This is the most advanced file structure available to GnuCOBOL programs. It’s not possible to describe the physical structure of such files because that structure will vary depending upon which advanced file-management facility was included into the GnuCOBOL build you will be using (Berkeley Database [BDB], VBISAM, etc.). We will — instead — discuss the logical structure of the file.

There will be multiple structures stored for an "INDEXED" file. The first will be a data component, which may be thought of as being similar to the internal structure of a relative file. Data records may not, however, be directly accessed by their record number as would be the case with a relative file, nor may they be processed sequentially by their physical sequence in the file.

The remaining structures will be one or more index components. An index component is a data structure that (somehow) enables the contents of a field, called a primary key, within each data record (a customer number, an employee number, a product code, a name, etc.) to be converted to a record number so that the data record for any given primary key value can be directly read, written and/or deleted. Additionally, the index data structure is defined in such a manner as to allow the file to be processed sequentially, record-by-record, in ascending sequence of the primary key field values. Whether this index structure exists as a binary-searchable tree structure (b-tree), an elaborate hash structure or something else is pretty much irrelevant to the programmer — the behaviour of the structure will be as it was just described. The actual mechanism used will depend upon the advanced file-management package was included into your GnuCOBOL implementation when it was built.

The runtime system will not allow two records to be written to an indexed file with the same primary key value.

The capability exists for an additional field to be defined as what is known as an alternate key. Alternate key fields behave just like primary keys, allowing both direct and sequential access to record data based upon the alternate key field values, with one exception. That exception is the fact that alternate keys may be allowed to have duplicate values, depending upon how the alternate key field is described to the GnuCOBOL compiler.

There may be any number of alternate keys, but each key field comes with a disk space penalty as well as an execution time penalty. As the number of alternate key fields increases, it will take longer and longer to write and/or modify records in the file.

These files can contain exact binary data fields. The contents of record fields are irrelevant to the reading process as there is no end-of-record delimiter.

All files are initially described to a GnuCOBOL program using a "SELECT" statement (see SELECT). In addition to defining a name by which the file will be referenced within the program, the "SELECT" statement will specify the name and path by which the file will be known to the operating system along with its organization, locking and sharing attributes.

A file description in the "FILE SECTION" (see FILE SECTION) will define the structure of records within the file, including whether or not variable-length records are possible and — if so — what the minimum and maximum length might be. In addition, the file description entry can specify file I/O block sizes.



1.3.9. Table Handling

The first can search a table sequentially, stopping only when either a table entry matching one of any number of search conditions is found, or when all table entries have been checked against the search criteria and none matched any of those criteria.

The second can perform an extremely fast search against a table sorted by and searched against a key field contained in each table entry. The algorithm used for such a search is a binary search (also known as a half-interval search). This algorithm ensures that only a small number of entries in the table need to be checked in order to find a desired entry or to determine that the desired entry doesn’t exist in the table. The larger the table, the more effective this search becomes. For example, a binary search of a table containing 32,768 entries will be able to locate a particular entry or determine the entry doesn’t exist by looking at no more than fifteen (15) entries! The algorithm is explained in detail in the documentation of the "SEARCH ALL" statement (see SEARCH ALL).

Finally, COBOL has the ability to perform in-place sorts of the data that is found in a table.



1.3.10. Sorting and Merging Data

A companion statement — "MERGE" (see MERGE) — can combine the contents of multiple files together, provided those files are all pre-sorted in a similar manner according to the same key structure. The resulting output will consist of the contents of all of the input files, merged together and sequenced according to the common key structure(s). The output generated by a "MERGE" statement may be written automatically to one or more output files or may be processed internally by the program.

A special form of the "SORT" statement also exists just to sort the data that resides in a table. This is particularly useful if you wish to use "SEARCH ALL" against the table.



1.3.11. String Manipulation Features

COBOL is no exception, although it does include some very powerful string manipulation capabilities; GnuCOBOL actually has even more string-manipulation capabilities than many other COBOL implementations. The following summarizes GnuCOBOL’s string-processing capabilities:

Concatenate two or more strings:


Conversion of a numeric time or date to a formatted character string:


Convert a binary value to its corresponding character in the program’s character set:


Convert a character string to lower-case:


Convert a character string to upper-case:


Convert a character string to only printable characters:


Convert a character to its numeric value in the program’s character set:


Count occurrences of sub strings in a larger string:


Decode a formatted numeric string back to a numeric value:


Determine the length of a string or data-item capable of storing strings:


Extract a sub string from a string based on its starting character position and length:


Format a numeric item for output, including thousands-separators ("," in the USA), currency symbols ("$" in the USA), decimal points, credit/Debit Symbols, Leading Or Trailing Sign Characters:


Justification (left, right or centred) of a string field:


Monoalphabetic substitution of one or more characters in a string with different characters:


Parse a string, breaking it up into sub strings based upon one or more delimiting character sequences1:


Removal of leading or trailing spaces from a string:


Substitution of a single sub string with another of the same length, based upon the sub strings starting character position and length:


Substitution of one or more sub strings in a string with replacement sub strings of the same length, regardless of where they occur:


Substitution of one or more sub strings in a string with replacement sub strings of a potentially different length, regardless of where they occur:



1.3.12. Screen Formatting Features

These features allow fields to be displayed at specific row/column positions, various colors and video attributes to be assigned to screen fields and the pressing of specific function keys (F1, F2, …) to be detectable. All of this takes place through the auspices of the "SCREEN SECTION" (see SCREEN SECTION) and special formats of the "ACCEPT" statement (see ACCEPT) and the "DISPLAY" statement (see DISPLAY).

The COBOL2002 standard, and therefore GnuCOBOL, only covers textual user interface (TUI) screens (those comprised of ASCII characters presented using a variety of visual attributes) and not the more-advanced graphical user interface (GUI) screen design and processing capabilities built into most modern operating systems. There are subroutine-based packages available that can do full GUI presentation — most of which may be called by GnuCOBOL programs, with a moderate research time investment (Tcl/Tk, for example) — but none are currently included with GnuCOBOL.



1.3.12.1. A Sample Screen

A Sample Screen Produced by a GnuCOBOL Program:

================================================================================
 GCic (2014/01/02 11:24) GnuCOBOL 2.1 23NOV2013 Interactive Compilation
+------------------------------------------------------------------------------+
: Filename: GCic.cbl                                                           :
: Folder:   E:\Programs\GCic\2013-11-23                                        :
+------------------------------------------------------------------------------+
 Set/Clr Switches Via F1-F9; Set Config Via F12; ENTER Key Compiles; ESC Quits
+------------------------------------------------------------------------------+
: F1  Assume WITH DEBUGGING MODE  F6 >"FUNCTION" Is Optional      : Current    :
: F2  Procedure+Statement Trace   F7 >Enable All Warnings         : Config:    :
: F3  Make a Library (DLL)        F8  Source Is Free-Format       : DEFAULT    :
: F4  Execute If Compilation OK   F9 >No COMP/BINARY Truncation   :            :
: F5  Listing Off                                                 :            :
+------------------------------------------------------------------------------+
 Extra "cobc" Switches, If Any ("-save-temps=xxx" Prevents Listings):
+------------------------------------------------------------------------------+
: ____________________________________________________________________________ :
: ____________________________________________________________________________ :
+------------------------------------------------------------------------------+
 Program Execution Arguments, If Any:
+------------------------------------------------------------------------------+
: ____________________________________________________________________________ :
: ____________________________________________________________________________ :
+------------------------------------------------------------------------------+
 GCic for Windows/MinGW Copyright (C) 2009-2014, Gary L. Cutler, GPL
================================================================================

The above screen was produced by the GnuCOBOL Interactive Compiler, or GCic. See GCic in GnuCOBOL Sample Programs, for the source and cross-reference listing of this program. PDF versions of this document will include an actual graphical image of this sample screen.

Screens are defined in the screen section of the data division. Once defined, screens are used at run-time via the "ACCEPT" and "DISPLAY" statements.



1.3.12.2. Color Palette and Video Attributes

GnuCOBOL supports the following visual attribute specifications in the "SCREEN SECTION" (see SCREEN SECTION):

Color

Eight (8) different colors may be specified for both the background (screen) and foreground (text) color of any row/column position on the screen. Colors are specified by number, although a copybook supplied with all GnuCOBOL distributions ("screenio.cpy") defines COB-COLOR-xxxxxx names for the various colors so they may be specified as a more meaningful name rather than a number. The eight colors, by number, with the constant names defined in screenio.cpy, are as follows:

  1. Black: COB-COLOR-BLACK
  2. Blue: COB-COLOR-BLUE
  3. Green: COB-COLOR-GREEN
  4. Cyan (Turquoise): COB-COLOR-CYAN
  5. Red: COB-COLOR-RED
  6. Magenta: COB-COLOR-MAGENTA
  7. Yellow: COB-COLOR-YELLOW
  8. White: COB-COLOR-WHITE
Text Brightness

There are three possible brightness levels supported for text — lowlight (dim), normal and highlight (bright). Not all GnuCOBOL implementations will support all three (some treat lowlight the same as normal). The deciding factor as to whether two or three levels are supported lies with the version of the "curses" package that is being used. This is a utility screen-IO package that is included into the GnuCOBOL run-time library when the GnuCOBOL software is built.

As a general rule of thumb, Windows implementations support two levels while Unix ones support all three.

Blinking

This too is a video feature that is dependent upon the "curses" package built into your version of GnuCOBOL. If blinking is enabled in that package, text displayed in fields defined in the screen section as being blinking will endlessly cycle between the brightest possible setting (highlight) and an "invisible" setting where the text color matches that of the field background color. A Windows build, which generally uses the "pcurses" package, will uses a brighter-than-normal background color to signify "blinking".

Reverse Video

This video attribute simply swaps the foreground and background colors and display options.

Field Outlining

It is possible, if supported by the "curses" package being used, to draw borders on the top, left and/or bottom edges of a field.

Secure Input

If desired, screen fields used as input fields may defined as "secure" fields, where each input character (regardless of what was actually typed) will appear as an asterisk (*) character. The actual character whose key was pressed will still be stored into the field in the program, however. This is very useful for password or account number fields.

Prompt Character

Input fields may have any character used as a fill character. These fill characters provide a visual indication of the size of the input field, and will automatically be transformed into spaces when the input field is processed by the program. If no such character is defined for an input field, an underscore ("_") will be assumed.



1.3.13. Report Writer Features

  1. Controlling the pagination of reports, including:
    1. The automatic production of a one-time notice on the first page of the report (report heading).
    2. The production of zero or more header lines at the top of every page of the report (page heading).
    3. The production of zero or more footer lines at the bottom of every page of the report (page footing).
    4. The automatic numbering of printed pages.
    5. The formatting of those report lines that make up the main body of the report (detail).
    6. Full awareness of where the "pen" is about to "write" on the current page, automatically forcing an eject to a new page, along with the automatic generation of a page footer to close the old page and/or a page header to begin the new one.
    7. The production of a one-time notice at the end of the last page of a report (report footing).
  2. Performing special reporting actions based upon the fact that the data being used to generate the report has been sorted according to one or more key fields:
    1. Automatically suppressing the presentation of one or more fields of data from the detail group when the value(s) of the field(s) duplicate those of the previously generated detail group. Fields such as these are referred to as group-indicate fields.
    2. Automatically causing suppressed detail group-indicate fields to re-appear should a detail group be printed on a new page.
    3. Recognizing when control fields on the report — fields tied to those that were used as "SORT" statement (see SORT) keys — have changed. This is known as a control break. The RWCS can automatically perform the following reporting actions when a control break occurs:
      • Producing a footer, known as a control footing after the detail lines that shared the same old value for the control field.
      • Producing a header, known as a control heading before the detail lines that share the same new value for the control field.
  3. Perform data summarise, as follows:
    1. Automatically generating subtotals in control and/or report footings, summarizing values of any fields in the detail group.
    2. Automatically generating crossfoot totals in detail groups. These would be sums of two or more values presented in the detail group.

The "REPORT SECTION" (see REPORT SECTION) documentation explores the description of reports and the "PROCEDURE DIVISION" (see PROCEDURE DIVISION) chapter documents the various language statements that actually produce reports. Before reading these, you might find it helpful to read Report Writer Usage Notes, which is dedicated to putting the pieces together for you.



1.3.14. Data Initialization

  1. When a program or subprogram is first executed, much of the data in it’s data division will be initialized as follows:

    The various sections of the data division each have their own rules as to when the actions described above will occur — consult the documentation on those sections for additional information.

    These default initialization rules can vary quite substantially from one COBOL implementation to another. For example, it is quite common for data division storage to be initialized to all binary zeros except for those data items where "VALUE" clauses are present. Take care when working with applications originally developed for another COBOL implementation to ensure that GnuCOBOL’s default initialization rules won’t prove disruptive.

  2. A programmer may use the "INITIALIZE" statement (see INITIALIZE) to initialise any group or elementary data item at any time. This statement provides far more initialization options than just the simple rules stated above.
  3. When the "ALLOCATE" statement (see ALLOCATE) statement is used to allocate a data item or to simply allocate an area of storage of a size specified on the "ALLOCATE", that allocation may occur with or without initialization, as per the programmer’s needs.


1.3.15. Syntax Diagram Conventions

MANDATORY-RESERVED-WORD
~~~~~~~~~~~~~~~~~~~~~~~

Reserved words of the COBOL language will appear in UPPER-CASE. When they appear underlined, as this one is, they are required reserved words.

OPTIONAL-RESERVED-WORD

When reserved words appear without underlining, as this one is, they are optional; such reserved words are available in the language syntax merely to improve readability — their presence or absence has no effect upon the program.

ABBREVIATION
~~~~

When only a portion of a reserved word is underlined, it indicates that the word may either be coded in its full form or may be abbreviated to the portion that is underlined.

substitutable-items

Generic terms representing user-defined substitutable items will be shown entirely in lower-case in syntax diagrams. When such items are referenced in text, they will appear as <substitutable-items>.

Complex-Syntax-Clause

Items appearing in Mixed Case within a syntax diagram represent complex clauses of other syntax elements that may appear in that position. Some COBOL syntax gets quite complicated, and using a convention such as this significantly reduces the complexity of a syntax diagram. When such items are referenced in text, they will appear as <<Complex-Syntax-Clause>>.

[ ]

Square bracket meta characters on syntax diagrams document language syntax that is optional. The [] characters themselves should not be coded. If a syntax diagram contains "a [b] c", the "a" and "c" syntax elements are mandatory but the "b" element is optional.

|

Vertical bar meta characters on syntax diagrams document simple choices. The | character itself should not be coded. If a syntax diagram contains "a|b|c", exactly one of the items "a", "b" or "c" must be selected.

{ xxxxxx }
{ yyyyyy }
{ zzzzzz }

A vertical list of items, bounded by multiple brace characters, is another way of signifying a choice between a series of items where exactly one item must be selected. This form is used to show choices when one or more of the selections is more complex than just a single word, or when there are too many choices to present horizontally with "|" meta characters.

| xxxxxx |
| yyyyyy |
| zzzzzz |

A vertical list of items, bounded by multiple vertical bar characters, signifies a choice between a series of items where one or more of the choices could be selected.

...

The ... meta character sequence signifies that the syntax element immediately preceding it may be repeated. The ... sequence itself should not be coded. If a syntax diagram contains "a b... c", syntax element "a" must be followed by at least one "b" element (possibly more) and the entire sequence must be terminated by a "c" syntax element.

{ }

The braces ({}) meta characters may be used to group a sequence of syntax elements together so that they may be treated as a single entity. The {} characters themselves should not be coded. These are typically used in combination with the "|" or "..." meta characters.

$*^()-+=:"'<,>./

Any of these characters appearing within a syntax diagram are to be interpreted literally, and are characters that must be coded — where allowed — in the statement whose format is being described. Note that a "." character is a literal character that must be coded on a statement whereas a "..." symbol is the meta character sequence described above.



1.3.16. Format of Program Source Lines

As of the COBOL2002 standard, a second mode now exists for COBOL source code statements — in this mode of operation, COBOL statements may each be up to 255 characters long, with no specific requirements as to what should appear in which columns.

Of course, in keeping with the long-standing COBOL tradition of maintaining backwards compatibility with older standards, programmers (and, of course, compliant COBOL compilers) are capable of working in either mode. It is even possible to switch back and forth in the same program. The terms ’Fixed Format Mode

The GnuCOBOL compiler (cobc) supports both of these source line format modes, defaulting to Fixed Format Mode lacking any other information.

The compiler can be instructed to operate in either mode in any of the following four ways:

  1. Using a compiler option switch — use the "-fixed" switch
  2. You may use the "SOURCEFORMAT AS FIXED" and "SOURCEFORMAT AS FREE" clauses of the ">>SET" CDF directive (see >>SET) within your source code to switch to Fixed or Free Format Mode, respectively.
  3. You may use the ">>FORMAT IS FIXED" and "FORMAT IS FREE" clauses of the ">>DEFINE" CDF directive (see >>DEFINE) within your source code to switch to Fixed or Free Format Mode, respectively.
  4. You may use the ">>SOURCE" CDF directive (see >>SOURCE) to switch to Free Format Mode (">>SOURCE FORMAT IS FREE") or Fixed Format Mode (">>SOURCE FORMAT IS FIXED".

Using methods 2-4 above, you may switch back and forth between the two formats at will.

The last three options above are all equivalent; all three are supported by GnuCOBOL so that source code compatibility may be maintained with a wide variety of other COBOL implementations. With all three, if the compiler is currently in Fixed Format Mode, the ">>" must begin in column 8 or beyond, provided no part of the directive extends past column 72. If the compiler is currently in Free Format Mode, the ">>" may appear in any column, provided no part of the directive extends past column 255.

Depending upon which source format mode the compiler is in, you will need to follow various rules for the format mode currently in effect. These rules are presented in the upcoming paragraphs.

The following discussion presents the various components of every GnuCOBOL source line record when the compiler is operating in Fixed Format Mode. Remember that this is the default mode for the GnuCOBOL compiler.

1-6

Historically, back in the days when punched-cards were used to submit COBOL program source to a COBOL compiler, this part of a COBOL statement was reserved for a six-digit sequence number. While the contents of this area are ignored by COBOL compilers, it existed so that a program actually punched on 80-character cards could — if the card deck were dropped on the floor — be run through a card sorter machine and restored to it’s proper sequence. Of course, this isn’t necessary today; if truth be told, it hasn’t been necessary for a long time.

See Marking Changes in Programs, for discussion of a valuable use to which the sequence number area may be put today.

7

Column 7 serves as an indicator in which one of five possible values will appear — space, "D" (or "d"), "-" (dash), "/" or "*". The meanings of these characters are as follows:

space

No special meaning — this is the normal character that will appear in this area.

D/d

The line contains a valid GnuCOBOL statement that is normally treated as a comment unless the program is being compiled in debugging mode.

*

The line is a comment.

/

The line is a comment that will also force a page eject in the compilation listing. While GnuCOBOL will honour such a line as a comment, it will not form-feed any generated listing.

-

The line is a continuation of the previous line. These are needed only when an alphanumeric literal (quoted character string), reserved word or user-defined word are being split across lines.


8-11

Language DIVISION, SECTION and paragraph section headers must begin in Area A, as must the level numbers 01, 77 in data description entries and the "FD" and "SD" file and SORT description headers.

12-72

All other COBOL programming language components are coded in these columns.

73-80

This is another obsolete area of COBOL statements. This part of every statement also hails back to the day when programs were punched on cards; it was expected that the name of the program (or at least the first 8 characters of it) would be punched here so that — if a dropped COBOL source deck contained more than one program — that handy card sorter machine could be used to first separate the cards by program name and then sort them by sequence number. Today’s COBOL compilers (including GnuCOBOL) simply ignore anything past column 72.

See Marking Changes in Programs, for discussion of a valuable use to which the program name area may be put today.



1.3.17. Program Structure

Complete GnuCOBOL Program Syntax
=======================================================================

 [ IDENTIFICATION DIVISION. ]
   ~~~~~~~~~~~~~~~~~~~~~~~
   PROGRAM-ID|FUNCTION-ID.  name-1 [ Program-Options ] .
   ~~~~~~~~~~ ~~~~~~~~~~~
 [ ENVIRONMENT DIVISION. ]
   ~~~~~~~~~~~ ~~~~~~~~
 [ CONFIGURATION SECTION. ]
   ~~~~~~~~~~~~~ ~~~~~~~
 [ SOURCE-COMPUTER.         Compilation-Computer-Specification . ]
   ~~~~~~~~~~~~~~~
 [ OBJECT-COMPUTER.         Execution-Computer-Specification . ]
   ~~~~~~~~~~~~~~~
 [ REPOSITORY.              Function-Specification... . ]
   ~~~~~~~~~~
 [ SPECIAL-NAMES.           Program-Configuration-Specification . ]
   ~~~~~~~~~~~~~
 [ INPUT-OUTPUT SECTION. ]
   ~~~~~~~~~~~~ ~~~~~~~
 [ FILE-CONTROL.            General-File-Description... . ]
   ~~~~~~~~~~~~
 [ I-O-CONTROL.             File-Buffering-Specification... . ]
   ~~~~~~~~~~~
 [ DATA DIVISION. ]
   ~~~~~~~~~~~~~
 [ FILE SECTION.            Detailed-File-Description... . ]
   ~~~~~~~~~~~~
 [ WORKING-STORAGE SECTION. Permanent-Data-Definition... . ]
   ~~~~~~~~~~~~~~~ ~~~~~~~
 [ LOCAL-STORAGE SECTION.   Temporary-Data-Definition... . ]
   ~~~~~~~~~~~~~ ~~~~~~~
 [ LINKAGE SECTION.         Subprogram-Argument-Description... . ]
   ~~~~~~~ ~~~~~~~
 [ REPORT SECTION.          Report-Description... . ]
   ~~~~~~ ~~~~~~~
 [ SCREEN SECTION.          Screen-Layout-Definition... . ]
   ~~~~~~ ~~~~~~~
   PROCEDURE DIVISION [ { USING Subprogram-Argument...      } ]
   ~~~~~~~~~ ~~~~~~~~   { ~~~~~                             }
                        { CHAINING Main-Program-Argument... }
                          ~~~~~~~~
                      [   RETURNING identifier-1 ] .
 [ DECLARATIVES. ]        ~~~~~~~~~
   ~~~~~~~~~~~~
 [ Event-Handler-Routine... . ]
 [ END DECLARATIVES. ]
   ~~~ ~~~~~~~~~~~~
   General-Program-Logic
 [ Nested-Subprogram... ]
 [ END PROGRAM|FUNCTION name-1 ]
   ~~~ ~~~~~~~ ~~~~~~~~

=======================================================================

Each program consists of up to four ’Divisions

  1. Not all divisions are needed in every program, but they must be specified in the order shown when they are used.
  2. The following points pertain to the identification division
  3. The following points pertain to the environment division:
  4. The following points pertain to the data division:
  5. The following points pertain to the procedure division:
  6. A single file of COBOL source code may contain:
  7. Subprogram "B" may be nested inside program "A" by including program B’s source code at the end of program A’s procedure division without an intervening "END PROGRAM A." or "END FUNCTION A." statement. For now, that’s all that will be said about nesting. See Independent vs Contained vs Nested Subprograms, for more information.
  8. Regardless of how many programs comprise a single GnuCOBOL source file, only a single output executable program will be generated from that source file when the file is compiled.


1.3.18. Comments

Comment TypeSource Mode — Description
Blank LinesFIXED — Blank lines may be inserted as desired. FREE — Blank lines may be inserted as desired.
Full-line commentsFIXED — An entire source line will be treated as a comment (and will be ignored by the compiler) by coding an asterisk ("*") in column seven (7). FREE — An entire source line will be treated as a comment (and will be ignored by the compiler) by coding the sequence "*>", starting in any column, as the first non-blank characters on the line.
Full-line comments with form-feedFIXED — An entire source line will be treated as a comment by coding a slash ("/") in column seven (7). Many COBOL compilers will also issue a form-feed in the program listing so that the "/" line is at the top of a new page. The GnuCOBOL compiler does not support this form-feed behaviour. The GnuCOBOL Interactive Compiler, or GCic, does support this form-feed behaviour when it generates program source listings! See GCic in GnuCOBOL Sample Programs, for the source and cross-reference listing (produced by GCic) of this program — you can see the effect of "/" there. FREE — There is no Free Source Mode equivalent to "/".
Partial-line commentsFIXED — Any text following the character sequence "*>" on a source line will be treated as a comment. The "*" must appear in column seven (7) or beyond. FREE — Any text following the character sequence "*>" on a source line will be treated as a comment. The "*" may appear in any column.
Comments that may be treated as code, typically for debugging purposesFIXED — By coding a "D" in column 7 FREE — By specifying the character sequence ">>D" Debugging statements may be compiled either by specifying the "-fdebugging-line" switch


1.3.19. Literals



1.3.19.1. Numeric Literals



1.3.19.2. Alphanumeric Literals

An alphanumeric literal is not valid for use in arithmetic expressions unless it is first converted to it’s numeric computational equivalent; there are three numeric conversion intrinsic functions built into GnuCOBOL that can perform this conversion — "NUMVAL" (see NUMVAL), "NUMVAL-C" (see NUMVAL-C) and "NUMVAL-F" (see NUMVAL-F).

Alphanumeric literals may take any of the following forms:


Alphanumeric literals too long to fit on a single line may be continued to the next line in one of two ways:

  1. If you are using Fixed Format Mode, the alphanumeric literal can be run right up to and including column 72. The literal may then be continued on the next line anywhere after column 11 by coding another quote or apostrophe (whichever was used to begin the literal originally). The continuation line must also have a hyphen (-)
         1         2         3         4         5         6         7   
1234567890123456789012345678901234567890123456789012345678901234567890123
 
       01  LONG-LITERAL-VALUE-DEMO     PIC X(60) VALUE "This is a long l
      -                                                "ong literal that
      -                                                " must be continu
      -                                                "ed.".
  1. Regardless of whether the compiler is operating in Fixed or Free Format Mode, GnuCOBOL allows alphanumeric literals to be broken up into separate fragments. These fragments have their own beginning and ending quote/apostrophe characters and are "glued together" at compilation time using "&"
         1         2         3         4         5         6         7   
1234567890123456789012345678901234567890123456789012345678901234567890123
 
      01  LONG-LITERAL-VALUE-DEMO      PIC X(60) VALUE "This is a" &
                                        " long literal that must " &
                                                    "be continued.".

If your program is using Free Format Mode, there’s less need to continue long alphanumeric literals because statements may be as long as 255 characters.

Numeric literals may be split across lines just as alphanumeric literals are, using either of the above techniques and both reserved and user-defined words can be split across lines too (using the first technique). The continuation of numeric literals and user-defined/reserved words is provided merely to provide compatibility with older COBOL versions and programs, but should not be used with new programs — it just makes for ugly-looking programs.



1.3.19.3. Figurative Constants

05 FILLER                PIC 9(10) VALUE ZEROS.
   ...
MOVE SPACES TO Employee-Name

But this is not:

CALL "SUBPGM" USING SPACES

The following are the GnuCOBOL figurative constants and their respective equivalent values.

"ZERO"

This figurative constant has a value of numeric 0 (zero). "ZEROS" and "ZEROES" are both synonyms of "ZERO".

"SPACE"

This figurative constant has a value of one or more space characters. "SPACES" is a synonym of "SPACE".

"QUOTE"

This figurative constant has a value of one or more double-quote characters ("). "QUOTES" is a synonym of "QUOTE".

"LOW-VALUE"

This figurative constant has a value of one or more of whatever character occupies the lowest position in the program’s collating sequence as defined in the "OBJECT-COMPUTER" (see OBJECT-COMPUTER) paragraph or — if no such specification was made — in whatever default character set the program is using (typically, this is the ASCII character set). "LOW-VALUES" is a synonym of "LOW-VALUE".

When the character set in use is ASCII with no collating sequence modifications, the "LOW-VALUES" figurative constant value is the ASCII "NUL" character. Because character sets can be redefined, however, you should not rely on this fact — use the "NULL" figurative constant instead.

"HIGH-VALUE"

This figurative constant has a value of one or more of whatever character occupies the highest position in the program’s collating sequence as defined in the "OBJECT-COMPUTER" paragraph or — if no such specification was made — in whatever default character set the program is using (typically, this is the ASCII character set). "HIGH-VALUES" is a synonym of "HIGH-VALUE".

"NULL"

A character comprised entirely of zero-bits (regardless of the programs collating sequence).


Programmers may create their own figurative constants via the "SYMBOLIC CHARACTERS" (see Symbolic-Characters-Clause) clause of the "SPECIAL-NAMES" (see SPECIAL-NAMES) paragraph.



1.3.20. Punctuation

The use of comma characters can cause confusion to a COBOL compiler if the "DECIMAL POINT IS COMMA" clause is used in the "SPECIAL-NAMES" (see SPECIAL-NAMES) paragraph, as might be the case in Europe. The following statement, which calls a subroutine passing it two arguments (the numeric constants 1 and 2):

CALL "SUBROUTINE" USING 1,2

Would — with "DECIMAL POINT IS COMMA" in effect — actually be interpreted as a subroutine call with 1 argument (the non-integer numeric literal whose value is 1 and 2 tenths). For this reason, it is best to always follow a comma with a space.

The period character (".")

The rules for where and when periods are needed in the procedure division are somewhat complicated. See Use of Periods, for the details.



1.3.21. LENGTH OF

LENGTH OF Syntax
=======================================================================

 LENGTH OF numeric-literal-1 | identifier-1
 ~~~~~~

=======================================================================

Alphanumeric literals and identifiers may optionally be prefixed with the "LENGTH OF" clause. The compile-time value generated by this clause will be the number of bytes in the alphanumeric literal or the defined size (in bytes) of the identifier.

  1. The reserved word "OF" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.

    Here is an example. The following two GnuCOBOL statements both display the same result (27):

    01  Demo-Identifier          PIC X(27).
    ...
        DISPLAY LENGTH OF "This is a LENGTH OF Example"
        DISPLAY LENGTH OF Demo-Identifier
    
  2. The "LENGTH OF" clause on a literal or identifier reference may generally be used anywhere a numeric literal might be specified, with the following exceptions:


1.3.22. Interfacing to Other Environments

Through the "CALL" statement, COBOL programs may invoke other COBOL programs serving as subprograms. This is quite similar to cross-program linkage capabilities provided by other languages. In GnuCOBOL’s case, the "CALL" facility is powerful enough to be tailored to the point where a GnuCOBOL program can communicate with operating system, database management and run-time library APIs, even if they weren’t written in COBOL themselves. See GnuCOBOL Main Programs CALLing C Subprograms, for an example of how a GnuCOBOL program could invoke a C-language subprogram, passing information back and forth between the two.

The fact that GnuCOBOL supports a full-featured two-way interface with C-language programs means that — even if you cannot access a library API directly — you could always do so via a small C "wrapper" program that is "CALL"ed by a GnuCOBOL program.


2. CDF - Compiler Directing Facility

When the compiler is operating in Fixed Format Mode, all CDF statements must begin in column eight (8) or beyond.

There are two types of supported CDF statements in GnuCOBOL — Text Manipulation Statements and Compiler Directives.

The CDF text manipulation statements "COPY" and "REPLACE" are used to introduce new code into programs either with or without changes, or may be used to modify existing statements already in the program. Text manipulation statements are always terminated with a period.

CDF directives, denoted by the presence of a ">>" character sequence as part of the statement name itself, are used to influence the process of program compilation.

Compiler directives are never terminated with a period.



2.1. >>CALL-CONVENTION

CDF >>CALL-CONVENTION Syntax
=======================================================================

 >>CALL-CONVENTION    { COBOL   }
 ~~~~~~~~~~~~~~~~~    { EXTERN  }
                      { STDCALL }
                      { STATIC  } 

=======================================================================
  1. COBOL (the default) the program name is treated as a COBOL word that maps to the externalised name program to be called, cancelled or referenced in the program-address-identifier, applying the same mapping rules as for a program name for which no AS phrase is specified.
  2. EXTERN the program name is treated as an external reference.
  3. STDCALL. < more info needed >
  4. STATIC the program name is called as a included element and not dynamically which is the normal default.


2.2. COPY

CDF COPY Statement Syntax
=======================================================================

 COPY copybook-name
 ~~~~
 [ IN|OF library-name ]
   ~~ ~~
 [ SUPPRESS PRINTING ]
   ~~~~~~~~
 [ REPLACING { Phrase-Clause | String-Clause }... ] .
   ~~~~~~~~~

=======================================================================
CDF COPY Phrase-Clause Syntax
=======================================================================

 { ==pseudo-text-1== } BY { ==pseudo-text-2== }
 { identifier-1      } ~~ { identifier-2      }
 { literal-1         }    { literal-2         }
 { word-1            }    { word-2            }

=======================================================================
CDF COPY String-Clause Syntax
=======================================================================

 [ LEADING|TRAILING ] ==partial-word-1== BY ==partial-word-2==
   ~~~~~~~ ~~~~~~~~                      ~~

=======================================================================
  1. "COPY" statements are used to import copybooks (see Copybooks) into a program.
  2. "COPY" statements may be used anywhere within a COBOL program where the code contained within the copybook would be syntactically valid.
  3. The optional "SUPPRESS"
  4. There is no difference between the use of the word "IN" and the word "OF" — use the one you prefer.
  5. A period is absolutely mandatory at the end of every "COPY" statement, even if the statement occurs within the scope of another one where a period might appear disruptive, such as within the scope of an "IF" (see IF) statement. This mandatory period at the end of the statement will not, however, affect the statement scope in which the "COPY" occurs.
  6. Both <pseudo-text-2> and <partial-word-2> may be null.
  7. All "COPY" statements are located and the contents of the corresponding copybooks inserted into the program source code before the actual compilation process begins. If a copybook contains a "COPY" statement, the copybook insertion process will be repeated to resolve the embedded "COPY". This will continue until no unresolved "COPY" statements remain. At that point, actual program compilation will begin.
  8. See Locating Copybooks, for the specific rules on how copybooks are located by the compiler.
  9. The optional "REPLACING"
    <<Phrase-Clause>>

    Replacement of one or more complete reserved words, user-defined identifiers or literals; the following points apply to this option:

    • This option cannot be used to replace part of a word, identifier or literal.
    • Whatever precedes the "BY" will be referred to here as the search string.
    • Single-item search strings can be specified by coding the "<identifier-1>", "<literal-1>" or "<word-1>" being replaced.
    • Multiple-item search strings can be specified using the "==<pseudo-text-1>==" option. For example, to replace all occurrences of "UPON PRINTER", you would specify "==UPON PRINTER==".
    • The replacement string, which follows the "BY", may be specified using any of the four options.
    • If the replacement string is a multiple-item phrase or is to be deleted altogether, you must use the "==<pseudo-text-2>==" option. If "<pseudo-text-2>" is null (in other words, the replacement text is specified as "===="), all encountered occurrences of the search string will be deleted.
    <<String-Clause>>

    Using this, you may replace character sequences that occur at the beginning ("LEADING"



2.3. REPLACE

CDF REPLACE Statement (Format 1) Syntax
=======================================================================

 REPLACE [ ALSO ] { Phrase-Clause | String-Clause }... .
 ~~~~~~~   ~~~~

=======================================================================
CDF REPLACE Statement (Format 2) Syntax
=======================================================================

 REPLACE [ LAST ] OFF .
 ~~~~~~~   ~~~~   ~~~

=======================================================================
CDF REPLACE Phrase-Clause Syntax
=======================================================================

 { ==pseudo-text-1== } BY { ==pseudo-text-2== }
                       ~~

=======================================================================
CDF REPLACE String-Clause Syntax
=======================================================================

 [ LEADING|TRAILING ] ==partial-word-1== BY ==partial-word-2==
   ~~~~~~~ ~~~~~~~~                      ~~

=======================================================================
  1. The "REPLACE" statement provides a mechanism for changing all or part of one or more GnuCOBOL statements.
  2. A period is absolutely mandatory at the end of every "REPLACE" statement (either format), even if the statement occurs within the scope of another one where a period might appear disruptive (such as within the scope of an "IF" (see IF) statement; the period will not, however, affect the statement scope in which the "REPLACE" occurs.
  3. The following points apply to Format 1 of the "REPLACE" statement:
    1. Format 1 of the "REPLACE" statement can be used to make changes to program source code in much the same way as the "REPLACING"
      <<Phrase-Clause>>

      Replace one or more complete reserved words, user-defined identifiers or literals; the following points apply to this option:

      • This option cannot be used to replace part of a word, identifier or literal.
      • Whatever precedes the "BY" will be referred to here as the search string.
      • Search strings on "REPLACE" are always specified using the "==<pseudo-text-1>==" option. For example, to replace all occurrences of "UPON PRINTER", you would specify "==UPON PRINTER==".
      • The replacement string, which follows the "BY", is specified using the "==<pseudo-text-2>==" option. If "<pseudo-text-2>" is null (in other words, the replacement text is specified as "===="), all encountered occurrences of the search string will be deleted.
      <<String-Clause>>

      Using this, you may replace character sequences that occur at the beginning ("LEADING"

    2. Once a Format 1 "REPLACE" statement is encountered in the currently-compiling source file, Replace Mode becomes active, and the change(s) specified by that statement will be automatically made on all subsequent source statements the compiler reads from the file.
    3. Replace Mode remains in-effect — continuing to make source code changes — until another Format 1 "REPLACE" is encountered, the end of currently compiling program source file is reached or a Format 2 "REPLACE" statement is encountered.
    4. When a Format 1 "REPLACE" statement with the "ALSO"
    5. When a Format 1 "REPLACE" without the "ALSO" keyword is encountered, any stacked change specification(s), if any, will be discarded and the currently in-effect change specification(s), if any, will be replaced by those of the new statement.
    6. When the end of the currently-compiling source file is reached, Replace Mode is deactivated and any stacked replace specifications will be discarded — compilation of the next source file (if any) will begin with Replace Mode inactive and no change specification(s) on the stack.
  4. The following points apply to Format 2 of the "REPLACE" statement:
    1. If Replace Mode is currently inactive, the Format 2 REPLACE statement will be ignored.
    2. If Replace Mode is currently active, a "REPLACE OFF." will deactivate Replace Mode and discard any replace specification(s) on the stack. The compiler will henceforth operate as if no "REPLACE" had ever been encountered, until such time as another Format 1 "REPLACE" is encountered.
    3. If Replace Mode is currently active, a "REPLACE LAST OFF." will replace the current replace specification(s) with those popped off the top of the stack. If there were no replace specification(s) on the stack, the effect will be as if a "REPLACE OFF." had been coded.


2.4. >>DEFINE

CDF >>DEFINE Directive Syntax
=======================================================================

 >>DEFINE [ CONSTANT ] cdf-variable-1 AS { OFF                    }
 ~~~~~~~~   ~~~~~~~~                     { ~~~                    }
                                         { literal-1 [ OVERRIDE ] }
                                         {             ~~~~~~~~   }
                                         { PARAMETER [ OVERRIDE ] }
                                           ~~~~~~~~~   ~~~~~~~~

=======================================================================
  1. The reserved word "AS" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. CDF variables defined in this way become undefined once an "END PROGRAM" or "END FUNCTION" directive is encountered in the input source.
  3. The ">>DEFINE" CDF directive is one way to create CDF variables that may be processed by other CDF statements such as ">>IF" (see >>IF). The ">>SET" CDF directive (see >>SET) provides another way to create them.
  4. CDF variable names follow the rules for standard GnuCOBOL user-defined names, and may not duplicate any CDF reserved word. CDF variable names may duplicate COBOL reserved words, provided the "CONSTANT"
  5. The "CONSTANT" option is valid only in conjunction with <literal-1>. When "CONSTANT" is specified, the CDF variable that is created may be used within your regular COBOL code as if it were a literal value. Without this option, the CDF variable may only be referenced on other CDF statements. The "OFF"
  6. The "PARAMETER"
  7. In the absence of the "OVERRIDE"


2.5. >>IF

CDF >>IF Directive Syntax
=======================================================================

 >>IF CDF-Conditional-Expression-1
 ~~~~     [ Program-Source-Lines-1 ]

 [ >>ELIF CDF-Conditional-Expression-2
   ~~~~~~ [ Program-Source-Lines-2 ] ]...

 [ >>ELSE
   ~~~~~~ [ Program-Source-Lines-3 ] ]

 >>END-IF
 ~~~~~~~~

=======================================================================
CDF-Conditional-Expression Syntax
=======================================================================

 { cdf-variable-1 } IS [ NOT ] { DEFINED                      }
 { literal-1      }      ~~~   { ~~~~~~~                      }
                               { SET                          }
                               { ~~~                          }
                               { CDF-RelOp { cdf-variable-2 } }
                               {           { literal-2      } }

=======================================================================
CDF-RelOp Syntax
=======================================================================

 >=    or    GREATER THAN OR EQUAL TO
             ~~~~~~~      ~~ ~~~~~
 >     or    GREATER THAN
             ~~~~~~~
 <=    or    LESS THAN OR EQUAL TO
             ~~~~      ~~ ~~~~~
 <     or    LESS THAN
             ~~~~
 =     or    EQUAL TO
             ~~~~~
 <>    or    EQUAL TO (with "NOT")
             ~~~~~

=======================================================================
  1. The reserved words "IS", "THAN" and "TO" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. Each ">>IF" directive must be terminated by an ">>END-IF"
  3. There may be any number of ">>ELIF"
  4. There may no more than one ">>ELSE"
  5. Only one of the <<Program-Source-Lines-n>> block of statements that lie within the scope of the ">>IF"-">>END-IF" may be processed by the compiler. Which one (if any) that gets processed will be decided as follows:
    1. Each <<CDF-Conditional-Expression-n>> will be evaluated, in turn, in the sequence in which they are coded in the >>IF statement and any ">>ELIF" clauses that may be present until one evaluates to TRUE. Once one of them evaluates to TRUE, the <<Program-Source-Lines-n>> block of code that corresponds to the TRUE <<CDF-Conditional-Expression-n>> will be one that is processed. All others within the ">>IF"-">>END-IF" scope will be ignored.
    2. If no <<CDF-Conditional-Expression>> evaluates to TRUE, and there is an ">>ELSE" clause, the <<Program-Source-Lines-3>> block of statements following the ">>ELSE" clause will be processed by the compiler and all others within the ">>IF"-">>END-IF" scope will be ignored.
    3. If no <<CDF-Conditional-Expression-n>> evaluates to TRUE and there is no ">>ELSE" clause, then none of the <<Program-Source-Lines-n>> block of statements within the ">>IF"-">>END-IF" scope will be processed by the compiler.
    4. If the <Program-Source-Lines-n>> statement block selected for processing is empty, no error results — there will just be no code generated from the ">>IF"-">>END-IF" structure.
  6. A <<Program-Source-Lines-n>> block may contain any valid COBOL or CDF code.
  7. The following points pertain to any <<CDF-Conditional-Expression-n>>:
    1. The "DEFINED"
    2. The "SET"
    3. Two CDF variables, two literals or a single CDF variable and a single literal may be compared against each other using a relational operator. Unlike the standard GnuCOBOL "IF" statement (see IF), multiple comparisons cannot be "AND"ed or "OR"ed together; you may nest a second ">>IF" inside the first, however, to simulate an "AND" and an "OR" may be simulated via the ">>ELIF" option.
    4. The "<>" symbol stands for "NOT EQUAL TO".


2.6. >>SET

CDF >>SET Directive Syntax
=======================================================================

 >>SET { [ CONSTANT ] cdf-variable-1 [ AS literal-1 ] }
 ~~~~~ {   ~~~~~~~~                    ~~             }
       { SOURCEFORMAT AS FIXED|FREE                   }
       { ~~~~~~~~~~~~    ~~~~~ ~~~~                   }
       { NOFOLDCOPYNAME                               }
       { ~~~~~~~~~~~~~~                               }
       { FOLDCOPYNAME AS UPPER|LOWER                  }
         ~~~~~~~~~~~~    ~~~~~ ~~~~~

=======================================================================
  1. The reserved word "AS" is optional (only on the "SOURCEFORMAT" and "FOLDCOPYNAME" clauses) and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. CDF variables defined in this way become undefined once an "END PROGRAM" or "END FUNCTION" directive is encountered in the input source.
  3. The "FOLDCOPYNAME"
  4. The "NOFOLDCOPYNAME"
  5. If the "CONSTANT"
  6. The remaining options of the ">>SET" CDF directive provide equivalent functionality to the ">>DEFINE" and ">>SOURCE" directives, as follows:
    1. ">>SET <cdf-variable-1>" ≡ ">>DEFINE <cdf-variable-1> AS OFF"
    2. ">>SET <cdf-variable-1> AS <literal-1>" ≡ ">>DEFINE <cdf-variable-1> AS <literal-1>"
    3. ">>SET CONSTANT <cdf-variable-1> AS <literal-1>" ≡ ">>DEFINE CONSTANT <cdf-variable-1> AS <literal-1>"
    4. ">>SET SOURCEFORMAT AS FIXED" ≡ ">>SOURCE FORMAT IS FIXED"
    5. ">>SET SOURCEFORMAT AS FREE" ≡ ">>SOURCE FORMAT IS FREE"


2.7. >>SOURCE

CDF >>SOURCE Directive Syntax
=======================================================================

 >>SOURCE FORMAT IS FIXED|FREE|VARIABLE
 ~~~~~~~~           ~~~~~ ~~~~ ~~~~~~~~

=======================================================================
  1. The reserved words "FORMAT" and "IS" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. You may switch between "FIXED" and "FREE" mode as desired.
  3. You may also use the ">>SET" CDF directive to perform this function.
  4. If the compiler is already in the specified mode, this statement will have no effect.


2.8. >>TURN

CDF >>TURN Directive Syntax
=======================================================================

 >>TURN { exception-name-1 [ file-name-1 ]... }...
 ~~~~~~
    { OFF                           }
    { ~~~                           }
    { CHECKING ON [ WITH LOCATION ] }
      ~~~~~~~~ ~~        ~~~~~~~~

=======================================================================


2.9. >>D

CDF >>D Directive Syntax
=======================================================================

 >>D
 ~~~

=======================================================================


2.10. >>DISPLAY

CDF >>DISPLAY Directive Syntax
=======================================================================

 >>DISPLAY source-text [ VCS = version-string ]
 ~~~~~~~~~               ~~~

=======================================================================


2.11. >>PAGE

CDF >>PAGE Directive Syntax
=======================================================================

 >>PAGE
 ~~~~~~

=======================================================================


2.12. >>LISTING

CDF >>LISTING Directive Syntax
=======================================================================

 >>LISTING  {ON}
 ~~~~~~~~~  {OFF}

=======================================================================


2.13. >>LEAP-SECONDS

CDF >>LEAP-SECONDS Directive Syntax
=======================================================================

 >>LEAP-SECONDS
 ~~~~~~~~~~~~~~

The ">>LEAP-SECONDS" CDF directive is syntactically recognized but is otherwise non-functional.


=======================================================================


2.14. * Directives

CDF * Directive Syntax
=======================================================================

 $ (Dollar) Directives - Active.

 These directives are active and have the same function as ones starting with >>:

 $DISPLAY ON|OFF
 $SET
 $IF
 $ELIF
 $ELSE-IF
 $END

 $ (Dollar) Directives - Not Active.
 These are NOT active and will produce a warning message:

 $DISPLAY VCS ...
 

=======================================================================

3. IDENTIFICATION DIVISION

IDENTIFICATION DIVISION Syntax
=======================================================================

[{ IDENTIFICATION } DIVISION. ]
 { ~~~~~~~~~~~~~~ } ~~~~~~~~
 { ID             }
    ~~  
 { PROGRAM-ID.  } program-id [ AS {literal-1    }] [ Type-Clause ] .
 { ~~~~~~~~~~   }                 {program name }]
 { FUNCTION-ID. } { literal-1 }   [ AS literal-2 ].
   ~~~~~~~~~~~    { function-name }
 { OPTIONS. }
   ~~~~~~~
 [ DEFAULT ROUNDED MODE IS {AWAY-FROM-ZERO         }
   ~~~~~~~ ~~~~~~~         {NEAREST-AWAY-FROM-ZERO } 
                           {NEAREST-EVEN           }
                           {NEAREST-TOWARDS-ZERO   }
                           {PROHIBITED             }
                           {TOWARDS-GREATER        }
                           {TOWARDS-LESSER         }
                           {TRUNCATION             }]
 [ ENTRY-CONVENTION IS {COBOL   }
   ~~~~~~~~~~~~~~~~    {EXTERN  }
                       {STDCALL }]                       
 [ AUTHOR.        comment-1. ]
   ~~~~~~
 [ DATE-COMPILED. comment-2. ]
   ~~~~~~~~~~~~~
 [ DATE-MODIFIED. comment-3. ]
   ~~~~~~~~~~~~~
 [ DATE-WRITTEN.  comment-4. ]
   ~~~~~~~~~~~~
 [ INSTALLATION.  comment-5. ]
   ~~~~~~~~~~~~
 [ REMARKS.       comment-6. ]
   ~~~~~~~
 [ SECURITY.      comment-7. ]
   ~~~~~~~~

The "AUTHOR"


=======================================================================
PROGRAM-ID Type Clause Syntax
=======================================================================

 IS [ COMMON ] [ INITIAL|RECURSIVE PROGRAM ]
      ~~~~~~     ~~~~~~~ ~~~~~~~~~

=======================================================================

The identification division provides basic identification of the program by giving it a name and optionally defining some high-level characteristics via the eight pre-defined paragraphs that may be specified.

  1. The paragraphs shown above may be coded in any sequence.
  2. The reserved words "AS", "IS" and "PROGRAM" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  3. A Type Clause may be coded only when "PROGRAM-ID"
  4. While the actual "IDENTIFICATION DIVISION" or "ID DIVISION" header is optional, the "PROGRAM-ID" / "FUNCTION-ID"
  5. The compiler’s "-Wobsolete" switch
  6. If specified, <literal-1> must be an actual alphanumeric literal and may not be a figurative constant.
  7. The "PROGRAM-ID" and "FUNCTION-ID" paragraphs serve to identify the program to the external (i.e. operating system) environment. If there is no "AS" clause present, the <program-id> will serve as that external identification. If there is an "AS" clause specified, that specified literal will serve as the external identification. For the remainder of this document, that "external identification" will be referred to as the primary entry-point name.
  8. The "INITIAL", "COMMON" and "RECURSIVE" words are used only within subprograms serving as subroutines. Their purposes are as follows:
    1. "COMMON"
    2. The "RECURSIVE"

      User-defined functions (i.e. "FUNCTION-ID") are always recursive.

    3. The "INITIAL"

4. ENVIRONMENT DIVISION

ENVIRONMENT DIVISION Syntax
=======================================================================

   ENVIRONMENT DIVISION.
   ~~~~~~~~~~~ ~~~~~~~~
 [ CONFIGURATION SECTION. ]
   ~~~~~~~~~~~~~ ~~~~~~~~
 [ SOURCE-COMPUTER.         Compilation-Computer-Specification . ]
   ~~~~~~~~~~~~~~~
 [ OBJECT-COMPUTER.         Execution-Computer-Specification . ]
   ~~~~~~~~~~~~~~~
 [ SPECIAL-NAMES.           Program-Configuration-Specification . ]
   ~~~~~~~~~~~~~
 [ REPOSITORY.              Function-Specification... . ]
   ~~~~~~~~~~
 [ INPUT-OUTPUT SECTION. ]
   ~~~~~~~~~~~~ ~~~~~~~
 [ FILE-CONTROL.            General-File-Description... . ]
   ~~~~~~~~~~~~
 [ I-O-CONTROL.             File-Buffering Specification... . ]
   ~~~~~~~~~~~

=======================================================================


4.1. CONFIGURATION SECTION

CONFIGURATION SECTION Syntax
=======================================================================

   CONFIGURATION SECTION.
   ~~~~~~~~~~~~~ ~~~~~~~
 [ SOURCE-COMPUTER. Compilation-Computer-Specification . ]
   ~~~~~~~~~~~~~~~
 [ OBJECT-COMPUTER. Execution-Computer-Specification . ]
   ~~~~~~~~~~~~~~~
 [ SPECIAL-NAMES.   Program-Configuration-Specification . ]
   ~~~~~~~~~~~~~
 [ REPOSITORY.      Function-Specification... . ]
   ~~~~~~~~~~

=======================================================================
  1. The four paragraphs in this section may be specified in any order but if not in this order, a warning will be issued.
  2. The configuration section is not allowed in a nested subprogram — nested programs will inherit the configuration section settings of their parent program.
  3. If none of the features provided by the configuration section are required by a program, the entire "CONFIGURATION SECTION." header may be omitted from the program.


4.1.1. SOURCE-COMPUTER

SOURCE-COMPUTER Syntax
=======================================================================

 SOURCE-COMPUTER. computer-name [ WITH DEBUGGING MODE ] .
 ~~~~~~~~~~~~~~~                       ~~~~~~~~~ ~~~~

=======================================================================
  1. The reserved word "WITH" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. This paragraph is not allowed in a nested subprogram — nested programs will inherit the "SOURCE-COMPUTER" settings of their parent program.
  3. The value specified for <computer-name> is irrelevant, provided it is a valid COBOL word that does not match any GnuCOBOL reserved word. The <computer-name> value may include spaces. This need not match the <computer-name> used with the "OBJECT-COMPUTER" paragraph, if any.
  4. The "DEBUGGING MODE"
  5. Even without the "DEBUGGING MODE" clause, it is still possible to compile debugging lines. Debugging lines may also be compiled by specifying the "-fdebugging-line" switch


4.1.2. OBJECT-COMPUTER

OBJECT-COMPUTER Syntax
=======================================================================

 OBJECT-COMPUTER.  [ computer-name ]
 ~~~~~~~~~~~~~~~
 [ MEMORY SIZE IS integer-1 WORDS|CHARACTERS ]
   ~~~~~~ ~~~~              ~~~~~ ~~~~~~~~~~
 [ PROGRAM COLLATING SEQUENCE IS alphabet-name-1 ]
           ~~~~~~~~~
 [ SEGMENT-LIMIT IS integer-2 ]
   ~~~~~~~~~~~~~
 [ CHARACTER CLASSIFICATION IS { locale-name-1  } ]
             ~~~~~~~~~~~~~~    { LOCALE         }
                               { ~~~~~~         }
                               { USER-DEFAULT   }
                               { ~~~~~~~~~~~~   }
                               { SYSTEM-DEFAULT }
                                 ~~~~~~~~~~~~~~
 .

The "MEMORY SIZE"


=======================================================================
  1. The <computer-name>, if specified, must immediately follow the "OBJECT-COMPUTER" paragraph name. The remaining clauses may be coded in any sequence.
  2. The reserved words "CHARACTER", "IS", "PROGRAM" and "SEQUENCE" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  3. The value specified for <computer-name>, if any, is irrelevant provided it is a valid COBOL word that does not match any GnuCOBOL reserved word. The <computer-name> may include spaces. This need not match the <computer-name> used with the "SOURCE-COMPUTER" paragraph, if any.
  4. The "OBJECT-COMPUTER" paragraph is not allowed in a nested subprogram — nested programs will inherit the "OBJECT-COMPUTER" settings of their parent program.
  5. The "COLLATING SEQUENCE"
  6. If no "COLLATING SEQUENCE" clause is specified, the collating sequence implied by the character set native to the computer (usually ASCII) will be used.
  7. The optional "CLASSIFICATION"

    The meanings of the four locale specifications are as follows:

    1. <locale-name-1> references a "LOCALE" (see SPECIAL-NAMES) definition.
    2. The keyword "LOCALE" refers to the current locale (in effect at the time the program is executed)
    3. The keyword "USER-DEFAULT" references the default locale specified for the user currently executing this program.
    4. The keyword "SYSTEM-DEFAULT" denotes the default locale specified for the computer upon which the program is executing.
  8. Absence of a "CLASSIFICATION" clause will cause character classification to occur according to the rules for the computer’s native character set (ASCII, EBCDIC, …).


4.1.3. SPECIAL-NAMES

SPECIAL-NAMES Syntax
=======================================================================

 SPECIAL-NAMES.
 ~~~~~~~~~~~~~
  [ CALL-CONVENTION integer-1 IS mnemonic-name-1 ]
    ~~~~~~~~~~~~~~~
  [ CONSOLE IS CRT ]
    ~~~~~~~    ~~~
  [ CRT STATUS IS identifier-1 ]
    ~~~ ~~~~~~
  [ CURRENCY SIGN IS literal-1 ]
    ~~~~~~~~ ~~~~
  [ CURSOR IS identifier-2 ]
    ~~~~~~
  [ DECIMAL-POINT IS COMMA ]
    ~~~~~~~~~~~~~    ~~~~~
  [ EVENT STATUS IS identifier-3 ]
    ~~~~~ ~~~~~~
  [ LOCALE locale-name-1 IS literal-2 ]...
    ~~~~~~
  [ NUMERIC SIGN IS TRAILING SEPARATE ]
    ~~~~~~~ ~~~~    ~~~~~~~~ ~~~~~~~~
  [ SCREEN CONTROL IS identifier-4 ]
    ~~~~~~ ~~~~~~~
  [ device-name-1 IS mnemonic-name-2 ]...

  [ feature-name-1 IS mnemonic-name-3 ]...

  [ Alphabet-Clause ]...

  [ Class-Definition-Clause ]...

  [ Switch-Definition-Clause ]...

  [ Symbolic-Characters-Clause ]...
  .

The "EVENT STATUS"


=======================================================================
<<Alphabet-Name-Clause>>, <<Class-Definition-Clause>>,
<<Switch-Definition-Clause>> and <<Symbolic-Characters-Clause>>
are discussed in detail in the next four sections.

The "SPECIAL-NAMES" paragraph provides a means for specifying various program and operating environment configuration options.

  1. The various clauses that may be specified within the "SPECIAL-NAMES" paragraph may be coded in any order.
  2. The reserved word "IS" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  3. The "SPECIAL-NAMES" paragraph is not allowed in a nested subprogram — nested programs will inherit the "SPECIAL-NAMES" settings of their parent program.
  4. Only the final clause specified within this paragraph should be terminated with a period.
  5. The "CALL-CONVENTION"
  6. The "CONSOLE IS CRT"
  7. If the "CRT STATUS"
  8. The "CURRENCY SIGN"
  9. The "CURSOR IS"
  10. The "DECIMAL POINT IS COMMA"
  11. The "LOCALE"
  12. The following is the list of possible locale codes, for example, that would be available on a Windows computer running a GnuCOBOL version that was built utilizing the MinGW Unix-emulator and the GNU C compiler (gcc):
    A

    af_ZA, am_ET, ar_AE, ar_BH, ar_DZ, ar_EG, ar_IQ, ar_JO, ar_KW, ar_LB, ar_LY, ar_MA, ar_OM, ar_QA, ar_SA, ar_SY, ar_TN, ar_YE, arn_CL, as_IN, az_Cyrl_AZ, az_Latn_AZ

    B

    ba_R, be_BY, bg_BG, bn_IN bo_BT, bo_CN, br_FR, bs_Cyrl_BA, bs_Latn_BA

    C

    ca_ES, cs_CZ, cy_GB

    D

    da_DK, de_AT, de_CH, de_DE, de_LI, de_LU, dsb_DE, dv_MV

    E

    el_GR, en_029, en_AU, en_BZ, en_CA, en_GB, en_IE, en_IN, en_JM, en_MY en_NZ, en_PH, en_SG, en_TT, en_US, en_ZA, en_ZW, es_AR, es_BO, es_CL, es_CO, es_CR, es_DO, es_EC, es_ES, es_GT, es_HN, es_MX, es_NI, es_PA, es_PE, es_PR, es_PY, es_SV, es_US, es_UY es_VE, et_EE, eu_ES

    F

    fa_IR, fi_FI, fil_PH, fo_FO, fr_BE, fr_CA, fr_CH, fr_FR, fr_LU, fr_MC, fy_NL

    G

    ga_IE, gbz_AF, gl_ES, gsw_FR, gu_IN

    H

    ha_Latn_NG, he_IL, hi_IN, hr_BA, hr_HR, hu_HU, hy_AM

    I

    id_ID, ig_NG, ii_CN, is_IS, it_CH, it_IT, iu_Cans_CA, iu_Latn_CA

    J

    ja_JP

    K

    ka_GE, kh_KH, kk_KZ, kl_GL, kn_IN, ko_KR, kok_IN, ky_KG

    L

    lb_LU, lo_LA, lt_LT, lv_LV

    M

    mi_NZ, mk_MK, ml_IN, mn_Cyrl_MN, mn_Mong_CN moh_CA, mr_IN, ms_BN, ms_MY, mt_MT

    N

    nb_NO, ne_NP, nl_BE, nl_NL, nn_NO, ns_ZA

    O

    oc_FR, or_IN

    P

    pa_IN, pl_PL, ps_AF, pt_BR, pt_PT

    Q

    qut_GT, quz_BO, quz_EC, quz_PE

    R

    rm_CH, ro_RO, ru_RU, rw_RW

    S

    sa_IN, sah_RU, se_FI, se_NO se_SE, si_LK, sk_SK, sl_SI, sma_NO, sma_SE, smj_NO, smj_SE, smn_FI, sms_FI, sq_AL, sr_Cyrl_BA, sr_Cyrl_CS, sr_Latn_BA, sr_Latn_CS, sv_FI, sv_SE, sw_KE syr_SY

    T

    ta_IN, te_IN, tg_Cyrl_TJ, th_TH tk_TM, tmz_Latn_DZ, tn_ZA, tr_IN, tr_TR, tt_RU

    U

    ug_CN, uk_UA, ur_PK, uz_Cyrl_UZ, uz_Latn_UZ

    V

    vi_VN

    W

    wen_DE, wo_SN

    X

    xh_ZA

    Y

    yo_NG

    Z

    zh_CN, zh_HK, zh_MO, zh_SG, zh_TW, zu_ZA

  13. The "NUMERIC SIGN TRAILING SEPARATE"
  14. The "<device-name-1> IS <mnemonic-name-2>" clause allows you to specify an alternate name (<device-name-1>) for one of the built-in GnuCOBOL device name <mnemonic-name-2>. The list of device names built-into GnuCOBOL, and the physical device associated with that name, are as follows:
    "CONSOLE"

    This is the (screen-mode) display of the PC or Unix system.

    "STDIN"
    "SYSIN"
    "SYSIPT"

    These devices (they are all synonymous) represent standard system input (pipe 0). On a PC or UNIX system, this is typically the keyboard. The contents of a file may be delivered to a GnuCOBOL program for access via one of these device names by adding the sequence "0< filename" to the end of the programs execution command.

    "PRINTER"
    "STDOUT"
    "SYSLIST"
    "SYSLST"
    "SYSOUT"

    These devices (they are all synonymous) represent standard system output (pipe 1). On a PC or UNIX system, this is typically the display. Output sent to one of these devices by a GnuCOBOL program can be sent to a file by adding the sequence "1> filename" to the end of the programs execution command.

    "STDERR"
    "SYSERR"

    These devices (they are synonymous) represent standard system error output (pipe 2). On a PC or UNIX system, this is typically the display. Output sent to one of these devices by a GnuCOBOL program can be sent to a file by adding the sequence "2> filename" to the end of the programs execution command.

  15. The "<feature-name-1> IS <mnemonic-name-3>" clause allow for mnemonic names to be assigned to up to the 13 printer channel (i.e. vertical page positioning) position feature names "Cnn" (nn=01-12) and "CSP". Once a channel position has been assigned a mnemonic name, statements of the form "WRITE <record-name> AFTER ADVANCING <mnemonic-name-3>" may be coded to write the specified print record at the channel position assigned to <mnemonic-name-3>.

    Printers supporting channel positioning are generally mainframe-type line printers. When writing to printers that do not support channel positioning, a formfeed will be issued to the printer.

    The "CSP" positioning option stands for "No Spacing". Testing on a MinGW build of GnuCOBOL shows that this too results in a formfeed being issued.



4.1.3.1. Alphabet-Name-Clause

SPECIAL-NAMES Alphabet-Clause Syntax
=======================================================================

 ALPHABET alphabet-name-1 IS { ASCII             }
 ~~~~~~~~                    { ~~~~~             }
                             { EBCDIC            }
                             { ~~~~~~            }
                             { NATIVE            }
                             { ~~~~~~            }
                             { STANDARD-1        }
                             { ~~~~~~~~~~        }
                             { STANDARD-2        }
                             { ~~~~~~~~~~        }
                             { Literal-Clause... }

=======================================================================
SPECIAL-NAMES ALPHABET Literal-Clause Syntax
=======================================================================

 literal-1 [ { THRU|THROUGH literal-2 } ]
             { ~~~~ ~~~~~~~           }
             { {ALSO literal-3}...    }
                ~~~~

=======================================================================
  1. The reserved word "IS" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. The reserved words "THRU" and "THROUGH" are interchangeable.
  3. GnuCOBOL considers "ASCII"
  4. "NATIVE"
  5. The following points apply to using the <literal-n> specifications to compose a custom character set:
    1. The <literal-n> values are either integers or alphanumeric quoted characters. These represent a single character in the "NATIVE" character set, either by it’s actual text value (alphanumeric quoted character) or by ordinal position in the "NATIVE" character set (integer),
    2. The sequence in which characters are defined in this clause specifies the relative order those characters should have when comparisons are made using this alphabet.
    3. Character positions in this list do not affect the actual binary storage values used for the characters — binary values will still be those of the "NATIVE" character set.
    4. You may specify any of the figurative constants "SPACE", "SPACES", "ZERO", "ZEROS", "ZEROES", "QUOTE", "QUOTES", "HIGH-VALUE", "HIGH-VALUES", "LOW-VALUE" or "LOW-VALUES" for any of the <literal-1>, <literal-2> or <literal-3> specifications.
  6. Once you have defined an alphabet name, that alphabet name may be used on specifications in "CODE-SET", "COLLATING SEQUENCE", or "SYMBOLIC CHARACTERS" clauses elsewhere in the program.


4.1.3.2. Class-Definition-Clause

SPECIAL-NAMES Class-Definition-Clause Syntax
=======================================================================

 CLASS class-name-1 IS { literal-1 [ THRU|THROUGH literal-2 ] }...
 ~~~~~                               ~~~~ ~~~~~~~

=======================================================================
  1. The reserved word "IS" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. The reserved words "THRU" and "THROUGH" are interchangeable.
  3. Both <literal-1> and <literal-2> must be alphanumeric literals of length 1.
  4. The literal(s) specified on this clause define the possible characters that may be found in a data item’s value in order to be considered part of the class.
  5. For example, the following defines a class called "Hexadecimal", the definition of which specifies the only characters that may be present in an alphanumeric data item if that data item is to be part of the "Hexadecimal" class:
    CLASS Hexadecimal IS '0' THRU '9'
                         'A' THRU 'F'
                         'a' THRU 'f'
    
  6. Once class "Hexadecimal" has been defined, program code could then use a statement such as "IF input-item IS Hexadecimal" to determine if the value of characters in a data item are valid according to that class.


4.1.3.3. Switch-Definition-Clause

SPECIAL-NAMES Switch-Definition-Clause Syntax
=======================================================================

 switch-name-1 [ IS mnemonic-name-1 ]

   [ ON STATUS IS condition-name-1 ]
     ~~
   [ OFF STATUS IS condition-name-2 ]
     ~~~

=======================================================================
  1. The reserved words "IS" and "STATUS" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The valid <switch-name-1> names are "SWITCH-n"
  3. If the program is compiled with the "-fsyntax-extension" switch
  4. At execution time, each switch will be associated with a
  5. Each specified switch must have at least one of a "IS <mnemonic-name-1>", "ON STATUS" or an "OFF STATUS" option defined for it, otherwise there will be no way to reference the switch from within a GnuCOBOL program.
  6. The "IS <mnemonic-name-1>" syntax provides a means for setting the switch to either an ON or OFF value via the "SET" statement (see SET).
  7. The "ON STATUS"


4.1.3.4. Symbolic-Characters-Clause

SPECIAL-NAMES-Symbolic-Characters-Clause Syntax
=======================================================================

 SYMBOLIC CHARACTERS
 ~~~~~~~~
   { symbolic-character-1... IS|ARE integer-1... }...

   [ IN alphabet-name-1 ]
     ~~

=======================================================================
  1. The reserved words "ARE", "CHARACTERS" and "IS" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. There must be exactly as many <integer-1> values specified as there are <symbolic-character-1> names.
  3. Each symbolic character name will be associated with the corresponding <integer-1>th character in the alphabet named in the "IN" clause. The integer values are selecting characters from the alphabet by their ordinal position and not by their numeric value; thus, an integer of 15 will select the 15th character in the specified alphabet, regardless of the actual numeric value of the bit pattern that constitutes that character.
  4. If no <alphabet-name-1> is specified, the systems native character set will be assumed.
  5. The following two code examples define the same set of figurative constant names for five ASCII control characters (assuming that ASCII is the system’s native character set). The two examples are identical in their effects, even though the manner in which the figurative constants are defined is different.
    SYMBOLIC CHARACTERS NUL IS 1    SYMBOLIC CHARACTERS NUL SOH BEL DC1 DC2
                        SOH IS 2                    ARE   1   2   8  18  19
                        BEL IS 8
                        DC1 IS 18
                        DC2 IS 19
    


4.1.4. REPOSITORY

REPOSITORY Syntax
=======================================================================

 REPOSITORY.
 ~~~~~~~~~~
    FUNCTION { function-prototype-name-1 [ AS literal-1 ] }...
    ~~~~~~~~ {                             ~~             }
             { intrinsic-function-name-1 [ AS literal-2 ] }
             {                             ~~             }
             { intrinsic-function-name-2 INTRINSIC        }
             { ALL INTRINSIC             ~~~~~~~~~        }
               ~~~ ~~~~~~~~~

=======================================================================
  1. The "REPOSITORY" paragraph is not allowed in a nested subprogram — nested programs will inherit the "REPOSITORY" settings of their parent program.
  2. The "INTRINSIC"
  3. As an alternative to using the "ALL INTRINSIC"
  4. The <function-prototype-name-1> option is required to specify the name of a user-defined function your program will be using. Optionally, should you desire, you may specify an alias name by which you will reference that user-defined function. Should you wish, you may also use the "AS" clause to provide an alias name for a built-in intrinsic function.
  5. The following example enables all intrinsic functions to be specified without the use of the "FUNCTION" keyword, (2) names two user-defined functions named "MY-FUNCTION-1" and "MY-FUNCTION-2" that will be used by the program and (3) specifies the alias names "SIGMA" for the intrinsic function "STANDARD-DEVIATION" and "MF2" for "MY-FUNCTION-2".
    REPOSITORY.
        FUNCTION ALL INTRINSIC.
        FUNCTION MY-FUNCTION-1.
        FUNCTION MY-FUNCTION-2 AS "MF2".
        FUNCTION STANDARD-DEVIATION AS "SIGMA".
    

A special note about user-defined functions — because you must name a user-defined function that your program will be using in the "REPOSITORY" paragraph, you may always reference that function from your program’s procedure division without needing to use the "FUNCTION" keyword.



4.2. INPUT-OUTPUT SECTION

INPUT-OUTPUT SECTION Syntax
=======================================================================

 [ INPUT-OUTPUT SECTION. ]
   ~~~~~~~~~~~~ ~~~~~~~
 [ FILE-CONTROL. ]
   ~~~~~~~~~~~~
     [ SELECT-Statement... ]

 [ I-O-CONTROL. ]
   ~~~~~~~~~~~
     [ MULTIPLE-FILE-Statement ]

     [ SAME-RECORD-Statement ]

=======================================================================
  1. As the diagram shows, there are three types of statements that may occur in the two paragraphs of this section. If none of the statements are coded in a particular paragraph, the paragraph itself may be omitted, otherwise it is required.
  2. If neither paragraph is coded, the "INPUT-OUTPUT SECTION." header itself may be omitted, otherwise it is normally required.
  3. If the compiler "config" file you are using has "relaxed-syntax-check" set to "yes", the "FILE-CONTROL" and "I-O-CONTROL" paragraphs may be specified without the "INPUT-OUTPUT SECTION." header having been coded.
  4. If both statement types are coded in the "I-O-CONTROL" paragraph, the order in which those statements are coded is irrelevant.


4.2.1. SELECT

SELECT Statement Syntax
=======================================================================

 SELECT [ [ NOT ] OPTIONAL ] file-name-1
 ~~~~~~     ~~~   ~~~~~~~~
 [ ASSIGN { TO    } [{ EXTERNAL }] [{ DISC|DISK      }] [{ identifier-1 }] ]
   ~~~~~~ { USING }  { ~~~~~~~~ }   { ~~~~ ~~~~      }   { word-1       }
                     { DYNAMIC  }   { DISPLAY        }   { literal-1    }
                       ~~~~~~~      { ~~~~~~~        }
                                    { KEYBOARD       }
                                    { ~~~~~~~~       }
                                    { LINE ADVANCING }
                                    { ~~~~ ~~~~~~~~~ }
                                    { PRINTER        }
                                    { ~~~~~~~        }
                                    { RANDOM         }
                                    { ~~~~~~         }
                                    { TAPE           }
                                      ~~~~
 [ COLLATING SEQUENCE IS alphabet-name-1 ]
   ~~~~~~~~~
 [ FILE|SORT ] STATUS IS identifier-2 [ identifier-3 ] ]
   ~~~~ ~~~~   ~~~~~~
 [ LOCK MODE IS { MANUAL|AUTOMATIC                                } ]
   ~~~~         { ~~~~~~ ~~~~~~~~~                                }
                { EXCLUSIVE [ WITH { LOCK ON MULTIPLE RECORDS } ] }
                  ~~~~~~~~~        { ~~~~ ~~ ~~~~~~~~ ~~~~~~~ }
                                   { LOCK ON RECORD           }
 [ ORGANIZATION-Clause ]           { ~~~~ ~~ ~~~~~~           }
                                   { ROLLBACK                 }
 [ RECORD DELIMITER IS STANDARD-1 ]  ~~~~~~~~
   ~~~~~~ ~~~~~~~~~    ~~~~~~~~~~
 [ RESERVE integer-1 AREAS ]
   ~~~~~~~
 [ SHARING WITH { ALL OTHER } ]
   ~~~~~~~      { ~~~       }
                { NO OTHER  }
                { ~~        }
                { READ ONLY }
                  ~~~~ ~~~~

The "COLLATING SEQUENCE"


=======================================================================

The "SELECT" statement creates a definition of a file and links that COBOL definition to the external operating system environment.

  1. The reserved words "AREAS", "IS", "MODE", "OTHER", "SEQUENCE", "TO", "USING" and "WITH" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. After <file-name-1>, the various clauses may be coded in any sequence.
  3. A period must follow the last coded clause.
  4. The "OPTIONAL"
  5. The <file-name-1> value that you specify will be the name by which you will reference the file within your program. This name should be formed according to the rules for user-defined names (see User-Defined Words).
  6. The optional "ASSIGN" clause specifies how — at runtime, when <file-name-1> is opened — either a logical device (STDIN, STDOUT) or a file anywhere in one of the currently-mounted file systems will be associated with <file-name-1>, as follows:
    1. There are three components to the "ASSIGN" clause — a <<Type>> specification ("EXTERNAL", "DYNAMIC" or neither), a <<Device>> (the list of device choices) and a <<Locator>> (shown as a choice between <identifier-1>, <word-1> and <literal-1>).
    2. "ASSIGN TO DISC '<file-name-1>'" will be assumed if there is no "ASSIGN" clause on a "SELECT".
    3. If an "ASSIGN" clause is coded without a <<Device>>, the device "DISC" will be assumed.
    4. If a <<Locator>> clause is coded, the COBOL file <file-name-1> will be attached to a data file within any file system that is mounted and available to the executing program at the time <file-name-1> is opened. How that file is identified varies, depending upon the specified <<Locator>>, as follows:
      1. If <literal-1> is coded, the value of the literal will serve as the File Location String that will identify the data file.
      2. If <identifier-1> is coded, the value of the identifier will serve as the File Location String that will identify the data file.
      3. If <word-1> (a syntactically valid word not duplicating that of a reserved or user-defined word) is coded, and a <<Type>> of "EXTERNAL" is specified, <word-1> itself will serve as the File Location String that will identify the data file. If, however, a <<Type>> of "EXTERNAL" was not specified, the compiler will create a "PIC X(1024)" data item named <word-1> within the program; the contents of that data item at the time the program opens <file-name-1> will then serve as the File Location String that will identify the data file.
      4. File Location Strings will be discussed shortly.
    5. If no <<Locator>> is coded, <file-name-1> will be attached to a logical device or a file based upon the specified (or implied) <<Device>>, as follows:
      1. "DISC" or "DISK" will assume an attachment to a file named <file-name-1> in whatever directory is current at the time the file is opened.
      2. "DISPLAY" will assume an attachment to the "STDOUT" logical device; these files should only be used for output.
      3. "KEYBOARD" will assume an attachment to the "STDIN" logical device; these files should only be used for input.
      4. "PRINTER" will assume an attachment to the "LPT1" logical device/port; these files should only be used for output.
      5. "RANDOM" or "TAPE" will behave exactly as "DISC" does. These two additional <<Device>>s are provided to facilitate the compilation of COBOL source from other COBOL implementations.
    6. The "LINE ADVANCING" device requires that a <<Locator>> be specified; these files should only be used for output. A COBOL Line Advancing file will allow carriage-control characters such as line-feeds and form-feeds to be written to the attached operating system file, via the "ADVANCING" clause of the "WRITE" statement (see WRITE).
    7. File Location Strings are used (at runtime) to identify the path and filename to the data file that must be attached to <file-name-1> when that file is opened.
    8. If the compiler "config" file you used to compile the program with had a "filename-mapping" value of "yes", the GnuCOBOL runtime system will first attempt to identify a currently-defined environment variable whose value will serve as the data file’s path and filename, as follows:
      1. If the compiler "config" file (see Compiler Configuration Files) you used to compile the program specified "mf" as the "assign-clause" value, then the File Locator String will be interpreted according to Microfocus COBOL rules — namely, everything before the last "-" in the File Locator String will be ignored; the characters after the last "-" will be treated as the base of an environment variable name. If there is no "-" character in the File Locator String then the entire File Locator String will serve as the base of an environment variable name. This is the default behaviour for every config file except "ibm".
      2. If, on the other hand, the compiler "config" file you used to compile the program specified "mf" as the "assign-clause" value, then the File Locator String will be interpreted according to according to IBM COBOL rules — namely, the File Locator String is expected to be of the form "S-xxx" or "AS-xxx", in which case the "xxx" will be treated as the base of an environment variable name. If there is no "-" character in the File Locator String then the entire File Locator String will serve as the base of an environment variable name.
      3. Once an environment variable name base (let’s refer to it as "bbbb") has been determined, the runtime system will look for the first one of the following environment variables that exists, in this sequence:
        DD_bbbb
        dd_bbbb
        bbbb
        

        Windows systems are case-insensitive with regard to environment variables, so there is no difference between the first two when using a GnuCOBOL implementation built for either Windows/MinGW or native Windows.

        If an environment variable was found, it’s value will serve as the path and filename to the data file.

    9. If no environment variable was found, or the "config" file used to compile the program had a "filename-mapping" value of "no", then the File Locator String value will serve as the path and filename to the data file.
    10. Paths and file names may be specified on an absolute ("C:\Data\datafile.dat", "/Data/datafile.dat", …) or relative-to-the-current-directory ("Data\datafile.dat", "Data/datafile.dat", …) basis.

      There may not even be a path ("datafile.dat"), in which case the file must be in the current directory.

  7. The "FILE STATUS"
    CodeExplanation
    00Success
    02Success (Duplicate Record Key Written)
    05Success (Optional File Not Found)
    07Success (No Unit)
    10End of file reached if reading forward or beginning-of-file reached if reading backward
    14Out of key range
    21Key invalid
    22Attempt to duplicate key value
    23Key not found
    30Permanent I/O error
    31Inconsistent filename
    34Boundary violation
    35File not found
    37Permission denied
    38Closed with lock
    39Conflicting attribute
    41File already open
    42File not open
    43Read not done
    44Record overflow
    46Read error
    47"OPEN INPUT" denied (insufficient permissions to read file)
    48"OPEN OUTPUT" denied (insufficient permissions to write to file)
    49"OPEN I-O" denied (insufficient permissions to read and/or write file)
    51Record locked
    52End of page
    57"LINAGE" specifications invalid
    61File sharing failure
    91File not available
  8. The "SHARING"
  9. The "LOCK"
  10. A "SELECT" statement without an "ORGANIZATION" explicitly coded will be handled as if the following ORGANIZATION clause had been specified:
    ORGANIZATION IS SEQUENTIAL
        ACCESS MODE IS SEQUENTIAL
    


4.2.1.1. ORGANIZATION SEQUENTIAL

ORGANIZATION SEQUENTIAL Clause Syntax
=======================================================================

 [ ORGANIZATION|ORGANISATION IS ] RECORD BINARY SEQUENTIAL
   ~~~~~~~~~~~~ ~~~~~~~~~~~~                    ~~~~~~~~~~
    [ ACCESS MODE IS SEQUENTIAL ]
      ~~~~~~         ~~~~~~~~~~

=======================================================================
  1. The reserved words "BINARY", "IS", "MODE" and "RECORD" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved words "ORGANIZATION" and "ORGANISATION" are interchangeable.
  3. The phrase "ORGANIZATION IS" (and it’s internationalized alternative, "ORGANISATION IS") is optional to provide compatibility with those (few) COBOL implementations that consider "ORGANIZATION" to be optional. Most COBOL implementations do require the word "ORGANIZATION", so it should be used in new programs.
  4. These files cannot be prepared with any standard text-editing or word processing software as all such programs will embed delimiter characters at the end of records (use "ORGANIZATION IS LINE SEQUENTIAL" instead).
  5. These files may contain either "USAGE DISPLAY" or "USAGE COMPUTATIONAL" (of any variety) data since no binary data sequence can be accidentally interpreted as an end-of-record delimiter.
  6. While records in a "ORGANIZATION SEQUENTIAL" file may be defined as having variable-length records, the file will be structured in such a manner as to reserve space for each record equal to the size of the largest possible record, based on the file’s description in the "FILE SECTION".
  7. The "ACCESS MODE SEQUENTIAL"
  8. Sequential files are processed using the following statements:


4.2.1.2. ORGANIZATION LINE SEQUENTIAL

ORGANIZATION LINE SEQUENTIAL Clause Syntax
=======================================================================

 [ ORGANIZATION|ORGANISATION IS ] LINE SEQUENTIAL
   ~~~~~~~~~~~~ ~~~~~~~~~~~~      ~~~~ ~~~~~~~~~~
    [ ACCESS MODE IS SEQUENTIAL ]
      ~~~~~~         ~~~~~~~~~~
    [ PADDING CHARACTER IS literal-1 | identifier-1 ]
      ~~~~~~~

The "PADDING CHARACTER" clause is syntactically recognized but is otherwise non-functional.


=======================================================================
  1. The reserved words "CHARACTER", "IS" and "MODE" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved words "ORGANIZATION" and "ORGANISATION" are interchangeable.
  3. The phrase "ORGANIZATION IS" (and it’s internationalized alternative, "ORGANISATION IS") is optional to provide compatibility with those (few) COBOL implementations that consider that word to be optional. Most COBOL implementations do require the word "ORGANIZATION", so it should be used in new programs.
  4. This is the only "ORGANIZATION" valid for files that are assigned to the "PRINTER" device.
  5. These files may be created with any standard text-editing or word processing software capable of writing text files. Such files should not contain any "USAGE COMPUTATIONAL" or "BINARY" (of any variety) data since such fields could accidentally contain byte sequences that could be interpreted as an end-of-record delimiter.
  6. Both fixed- and variable-length record formats are supported.
  7. The end-of-record delimiter sequence will be X’0A’ (an ASCII line-feed character) or a X’0D0A’ (an ASCII carriage-return + line-feed sequence). The former is used on Unix implementations of GnuCOBOL (including Windows/MinGW, Windows/Cygwin and OSX implementations) while the latter would be used with native Windows implementations.
  8. When reading a "LINE SEQUENTIAL" file, records in excess of the size implied by the file’s description in the "FILE SECTION" will be truncated while records shorter than that size will be padded to the right with "SPACES".
  9. The "ACCESS MODE SEQUENTIAL"
  10. Files assigned to "PRINTER" or "CONSOLE" should be specified as "ORGANIZATION LINE SEQUENTIAL".
  11. Line Sequential files are processed using the following statements:


4.2.1.3. ORGANIZATION RELATIVE

ORGANIZATION RELATIVE Clause Syntax
=======================================================================

 [ ORGANIZATION|ORGANISATION IS ] RELATIVE
   ~~~~~~~~~~~~ ~~~~~~~~~~~~      ~~~~~~~~
    [ ACCESS MODE IS { SEQUENTIAL } ]
      ~~~~~~         { ~~~~~~~~~~ }
                     { DYNAMIC    }
                     { ~~~~~~~    }
                     { RANDOM     }
                       ~~~~~~
    [ RELATIVE KEY IS identifier-1 ]
      ~~~~~~~~

=======================================================================
  1. The reserved words "IS", "KEY" and "MODE" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved words "ORGANIZATION" and "ORGANISATION" are interchangeable.
  3. The phrase "ORGANIZATION IS" (and it’s internationalized alternative, "ORGANISATION IS") is optional to provide compatibility with those (few) COBOL implementations that consider that word to be optional. Most COBOL implementations do require the word "ORGANIZATION", so it should be used in new programs.
  4. "ORGANIZATION RELATIVE" files cannot be assigned to the "CONSOLE", "DISPLAY", "LINE ADVANCING" or "PRINTER" devices.
  5. The "RELATIVE KEY"
  6. While an "ORGANIZATION RELATIVE" file may be defined as having variable-length records, the file will be structured in such a manner as to reserve space for each record equal to the size of the largest possible record as defined by the file’s description in the "FILE SECTION".
  7. "ACCESS MODE SEQUENTIAL", the default "ACCESS MODE" if none is specified, indicates that the records of the file will be processed in a sequential manner, according to their physical sequence in the file.
  8. "ACCESS MODE RANDOM"
  9. "ACCESS MODE DYNAMIC"
  10. The "RELATIVE KEY"
  11. Relative files are processed using the following statements:


4.2.1.4. ORGANIZATION INDEXED

ORGANIZATION INDEXED Clause Syntax
=======================================================================

 [ ORGANIZATION|ORGANISATION IS ] INDEXED
   ~~~~~~~~~~~~ ~~~~~~~~~~~~      ~~~~~~~
    [ ACCESS MODE IS { SEQUENTIAL } ]
      ~~~~~~         { ~~~~~~~~~  }
                     { DYNAMIC    }
                     { ~~~~~~~    }
                     { RANDOM     }
                       ~~~~~~
    [ RECORD KEY IS identifier-1
      ~~~~~~
          [ =|{SOURCE IS} identifier-2 ] ]
               ~~~~~~
    [ ALTERNATE RECORD KEY IS identifier-3
      ~~~~~~~~~ ~~~~~~
          [ =|{SOURCE IS} identifier-4 ]
               ~~~~~~
          [ WITH DUPLICATES ] ]...
                 ~~~~~~~~~~

The "SOURCE" clause is syntactically recognized but is otherwise non-functional. It is supported to provide compatibility with COBOL source written for other COBOL implementations.


=======================================================================
  1. The reserved words "IS", "KEY" and "MODE" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved words "ORGANIZATION" and "ORGANISATION" are interchangeable.
  3. The phrase "ORGANIZATION IS" (and it’s internationalized alternative, "ORGANISATION IS") is optional to provide compatibility with those (few) COBOL implementations that consider that word to be optional. Most COBOL implementations do require the word "ORGANIZATION", so it should be used in new programs.
  4. "ORGANIZATION INDEXED" files cannot be assigned to "CONSOLE", "DISPLAY", "KEYBOARD", "LINE ADVANCING" or "PRINTER".
  5. "ACCESS MODE SEQUENTIAL"
  6. "ACCESS MODE RANDOM"
  7. "ACCESS MODE DYNAMIC"
  8. The "PRIMARY KEY"
  9. The "ALTERNATE RECORD KEY"
  10. There may be multiple "ALTERNATE RECORD KEY" clauses, each defining an additional alternate key for the file.
  11. Indexed files are processed using the following statements:


4.2.2. SAME RECORD AREA

I-O-CONTROL SAME AREA Syntax
=======================================================================

 SAME { SORT-MERGE } AREA FOR file-name-1... .
 ~~~~ { ~~~~~~~~~~ }
      { SORT       }
      { ~~~~       }
      { RECORD     }
        ~~~~~~

The "SAME SORT-MERGE"


=======================================================================
  1. The reserved words "AREA" and "FOR" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. This statement must be terminated with a period.
  3. While coding only a single file name (the repeated <file-name-1> item) is syntactically valid, this statement will have no effect upon the program unless at least two files are specified.
  4. The effect of this statement will be to cause the specified files to share the same I/O buffer in memory. These buffers can sometimes get quite large, and by having multiple files share the same buffer memory you may significantly cut down the amount of memory the program is using (thus making "room" for more procedural code or data). If you do use this feature, take care to ensure that no more than one of the specified files are ever OPEN simultaneously.


4.2.3. MULTIPLE FILE

I-O-CONTROL MULTIPLE FILE Syntax
=======================================================================

 MULTIPLE FILE TAPE CONTAINS
 ~~~~~~~~
    { file-name-1 [ POSITION integer-1 ] }...
                    ~~~~~~~~
    .

The "MULTIPLE FILE TAPE" clause is obsolete and is therefore recognized but not functional.


=======================================================================

5. DATA DIVISION

DATA DIVISION Syntax
=======================================================================

   DATA DIVISION.
   ~~~~ ~~~~~~~~
 [ FILE SECTION.
   ~~~~ ~~~~~~~
   { File/Sort-Description [ { FILE-SECTION-Data-Item } ]... }... ]
   {                         { 01-Level-Constant      }      }
   {                         { 78-Level-Constant      }      }
   { 01-Level-Constant                                       }
   { 78-Level-Constant                                       }
 [ WORKING-STORAGE SECTION.
   ~~~~~~~~~~~~~~~ ~~~~~~~
   [ { WORKING-STORAGE-SECTION-Data-Item } ]... ]
     { 01-Level-Constant                 }
     { 78-Level-Constant                 }
 [ LOCAL-STORAGE SECTION.
   ~~~~~~~~~~~~~ ~~~~~~~
   [ { LOCAL-STORAGE-SECTION-Data-Item } ]... ]
     { 01-Level-Constant               }
     { 78-Level-Constant               }
 [ LINKAGE SECTION.
   ~~~~~~~ ~~~~~~~
   [ { LINKAGE-SECTION-Data-Item } ]... ]
     { 01-Level-Constant         }
     { 78-Level-Constant         }
 [ REPORT SECTION.
   ~~~~~~ ~~~~~~~
   { Report-Description [ { Report-Group-Definition } ]... }... ]
   {                      { 01-Level-Constant       }      }
   {                      { 78-Level-Constant       }      }
   { 01-Level-Constant                                     }
   { 78-Level-Constant                                     }
 [ SCREEN SECTION.
   ~~~~~~ ~~~~~~~
   [ { SCREEN-SECTION-Data-Item } ]... ]
     { 01-Level-Constant        }
     { 78-Level-Constant        }

=======================================================================
  1. If no data will be described in one of the data division sections, that section header may be omitted.
  2. If no data division sections are needed, the "DATA DIVISION." header itself may be omitted.
  3. If more than one section is needed in the data division (a common situation), the sections must be coded in the sequence they are presented above.


5.1. Data Definition Principles


The "Employee" data item consists of two subordinate data items — an "Employee-Name" and an "Employment-Dates" data item (presumably there would be a lot of others too, but we don’t care about them right now). As the diagram shows, each of those data items are, in turn, broken down into subordinate data items. This hierarchy of data items can get rather "deep", and GnuCOBOL, like other COBOL implementations, can handle up to 49 levels of such hierarchical structures.

As was presented earlier (see Structured Data), a data item that is broken down into other data items is referred to as a group item, while one that isn’t broken down is called an elementary item.

COBOL uses the concept of a "level number" to indicate the level at which a data item occurs in a data structure such as the example shown above. When these data items are defined, they are all defined together with a number in the range 1-49 specified in front of their names. Over the years, a convention has come to exist among COBOL programmers that level numbers are always coded as two-digit numbers — they don’t have to be specified as two-digit numbers, but every example you see in this document will take that approach!

The data item at the top, also referred to as a "record", always has a level number of 01. After that, you may assign level numbers as you wish (01–02–03–04…, 01–05–10–15…, etc.), as long as you follow these simple rules:

  1. Every data item at the same "level" of a hierarchy diagram such as the one you see here (if you were to make one, which you rarely — if ever — will, once you get used to this concept) must have the same level number.
  2. Every new level uses a level number that is strictly greater than the one used in the parent (next higher) level.
  3. When describing data hierarchies, you may never use a level number greater than 49 (except for 66, 77, 78 and 88 which have very special meanings — see see Special Data Items).

So, the definition of these data items in a GnuCOBOL program would go something like this:

    01  Employee
        05 Employee-Name
           10 Last-Name
           10 First-Name
           10 Middle-Initial
        05 Employment-Dates
           10 From-Date
              15 Year
              15 Month
              15 Day
           10 To-Date
              15 Year
              15 Month
              15 Day

The indentation is purely at the discretion of the programmer to make things easier for humans to read (the compiler couldn’t care less). Historically, COBOL implementations that required Fixed Format Mode source programs required that the "01" level number begin in Area A and that everything else begins in Area B. GnuCOBOL only requires that all data definition syntax occur in columns 8-72. In Free Format Mode, of course, there aren’t even those limitations.

Did you notice that there are two each of "Year", "Month" and "Day" data names defined? That’s perfectly legal, provided that each can be uniquely "qualified" so as to be distinct from the other. Take for example the "Year" items. One is defined as part of the "From-Date" data item while the other is defined as part of the "To-Date" data item. In COBOL, we would actually code references to these two data items as either "Year OF From-Date" and "Year OF To-Date" or "Year IN From-Date" and "Year IN To-Date" (COBOL allows either "IN" or "OF" to be used). Since these references would clarify any confusion to us as to which "Year" might be referenced, the GnuCOBOL compiler won’t be confused either.

The coding example shown above is incomplete — it only describes the data item names and their hierarchical relationships to one other. In addition, any valid data item definitions will also need to describe what type of data is to be contained in a data item (Numeric? Alphanumeric? Alphabetic?), how much data can be held in the data item and a multitude of other characteristics.

When group items are being defined, subordinate items may be assigned a "name" of "FILLER"



5.2. FILE SECTION

FILE SECTION Syntax
=======================================================================

 [ FILE SECTION.
   ~~~~ ~~~~~~~
   { File/Sort-Description [ { FILE-SECTION-Data-Item } ]... }... ]
   {                         { 01-Level-Constant      }      }
   {                         { 78-Level-Constant      }      }
   { 01-Level-Constant                                       }
   { 78-Level-Constant                                       }

=======================================================================

Files destined for use as sort/merge work files must be described with a Sort/Merge File Description ("SD") while every other file is described with a File Description ("FD"). Each of these descriptions will almost always be followed with at least one record description.



5.2.1. File/Sort-Description

File/Sort-Description Syntax
=======================================================================

 FD|SD file-name-1 [ IS EXTERNAL|GLOBAL ]
 ~~ ~~                  ~~~~~~~~ ~~~~~~
 [ BLOCK CONTAINS [ integer-1 TO ] integer-2 CHARACTERS|RECORDS ]
   ~~~~~                      ~~             ~~~~~~~~~~ ~~~~~~~
 [ CODE-SET IS alphabet-name-1 ]
   ~~~~~~~~
 [ DATA { RECORD IS   } identifier-1... ]
   ~~~~ { ~~~~~~      }
        { RECORDS ARE }
          ~~~~~~~
 [ LABEL { RECORD IS   } OMITTED|STANDARD ]
   ~~~~~ { ~~~~~~      } ~~~~~~~ ~~~~~~~~
         { RECORDS ARE }
           ~~~~~~~
 [ LINAGE IS integer-3 | identifier-2 LINES
   ~~~~~~
     [ LINES AT BOTTOM integer-4 | identifier-3 ]
                ~~~~~~
     [ LINES AT TOP integer-5 | identifier-4 ]
                ~~~
     [ WITH FOOTING AT integer-6 | identifier-5 ] ]
            ~~~~~~~
 [ RECORD { CONTAINS [ integer-7 TO ] integer-8 CHARACTERS   } ]
   ~~~~~~ {                      ~~                          }
          { IS VARYING IN SIZE                               }
          {    ~~~~~~~                                       }
          {     [ FROM [ integer-7 TO ] integer-8 CHARACTERS }
          {                        ~~                        }
          {         DEPENDING ON identifier-6 ]              }
                    ~~~~~~~~~
 [ RECORDING MODE IS recording-mode ]
   ~~~~~~~~~
 [ { REPORT IS   } report-name-1... ]
   { ~~~~~~      }
   { REPORTS ARE }
     ~~~~~~~
 [ VALUE OF implementor-name-1 IS literal-1 | identifier-7 ] .
   ~~~~~ ~~

The "BLOCK CONTAINS"


=======================================================================
  1. The reserved words "ARE", "AT", "CHARACTERS" ("RECORD" clause only), "CONTAINS", "FROM", "IN", "IS", "ON" and "WITH" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The terms "RECORD IS" and "RECORDS ARE" are interchangeable.
  3. The terms "REPORT IS" and "REPORTS ARE" are interchangeable.
  4. Only files intended for use as work files for either the "SORT" (see SORT) or "MERGE" (see MERGE) statements should be coded with an SD — all others should be defined with a FD.
  5. The sequence in which files are defined via "FD" or "SD", as compared to the sequence in which their "SELECT" statements were coded, is irrelevant.
  6. The name specified as <file-name-1> must exactly match the name specified on the file’s "SELECT" statement.
  7. The "CODE-SET"
  8. The "LINAGE" clause may only be specified in the "FD" of a sequential or line sequential file. If used with a sequential file, the organization of that file will be implicitly changed to line sequential. The various components of the "LINAGE" clause define the layout of printed pages as follows:
  9. This page structure — once defined — can be automatically enforced by the "WRITE" statement (see WRITE).
  10. Specifying a "LINAGE" clause in an "FD" will cause the "LINAGE-COUNTER" special register to be created for the file. This automatically-created data item will always contain the current relative line number on the page being prepared which will serve as the starting point for a "WRITE" statement.
  11. The "RECORD CONTAINS"
  12. The "REPORT IS"
    1. The clause may only be specified in the "FD" of a sequential or line sequential file. If used with a sequential file, the organization of that file will be implicitly changed to line sequential.
    2. The "FD" cannot be followed by record descriptions — detailed descriptions of data to be printed to the file will be defined in the "REPORT SECTION" (see REPORT SECTION).
    3. If a "LINAGE" clause is also specified, Values specified for "LINAGE IS" and "FOOTING AT" will be ignored. The values of "LINES AT BOTTOM" and "LINES AT TOP", if any, will be honoured.
  13. The following special rules apply only to sort/merge work files:
    1. Sort/merge work files should be assigned to "DISK" (or "DISC") on their "SELECT" statements.
    2. Sorts and merges will be performed in memory, if the amount of data being sorted allows.
    3. Should actual disk work files be necessary due to the amount of data being sorted or merged, they will be automatically allocated to disk in a folder defined by:
      • The
      • The
      • The

      (in that order)

    4. These disk files will be automatically purged upon "SORT" or "MERGE" termination. They will also be purged if the program terminates abnormally before the "SORT" or "MERGE" finishes. Should you ever need to know, temporary sort/merge work files will be named "cob*.tmp".
    5. If you specify a specific filename in the sort/merge work file’s "SELECT", it will be ignored.
  14. See Data Description Clauses, for information on the "EXTERNAL" and "GLOBAL" options.


5.2.2. FILE-SECTION-Data-Item

FILE-SECTION-Data-Item Syntax
=======================================================================

 level-number [ identifier-1 | FILLER ] [ IS GLOBAL|EXTERNAL ]
                               ~~~~~~        ~~~~~~ ~~~~~~~~
 [ BLANK WHEN ZERO ]
   ~~~~~      ~~~~
 [ JUSTIFIED RIGHT ]
   ~~~~
 [ OCCURS [ integer-1 TO ] integer-2 TIMES
   ~~~~~~             ~~
        [ DEPENDING ON identifier-2 ]
          ~~~~~~~~~
        [ ASCENDING|DESCENDING KEY IS identifier-3 ]
          ~~~~~~~~~ ~~~~~~~~~~
        [ INDEXED BY identifier-4 ] ]
          ~~~~~~~
 [ PICTURE IS picture-string ]
   ~~~
 [ REDEFINES identifier-5 ]
   ~~~~~~~~~
 [ SIGN IS LEADING|TRAILING [ SEPARATE [CHARACTER] ] ]
   ~~~~    ~~~~~~~ ~~~~~~~~   ~~~~~~~~
 [ SYNCRONIZED|SYNCHRONISED [ LEFT|RIGHT ] ]
   ~~~~        ~~~~           ~~~~ ~~~~~
 [ USAGE IS data-item-usage ] . [ FILE-SECTION-Data-Item ]...
   ~~~~~

The "LEFT" and "RIGHT" (SYNCRONIZED) clauses are syntactically recognized but are otherwise non-functional.


=======================================================================
  1. The reserved words "BY", "IS", "KEY", "ON" and "WHEN" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved words "SYNCRONIZED" and "SYNCRONIZED" are interchangeable. Both may be abbreviated to "SYNC".
  3. The reserved word "PICTURE" may be abbreviated to "PIC".
  4. As the syntax diagram shows, the definition of a <<FILE-SECTION-Data-Item>> is a recursive one in that there may be any number of such specifications coded following a FD or SD. The first such specification must have a level number of 01, and will describe a specific format of data record within the file. Specifications that follow that one may have level numbers greater than 01, in which case they are defining a hierarchical breakdown of the record. The definition of a record is terminated when one of the following occurs:
  5. Every <<FILE-SECTION-Data-Item>> description must be terminated with a period.
  6. If there are multiple record descriptions present for a given "FD" or "SD", the one with the longest length will define the size of the record buffer into which a "READ" statement (see READ) or a "RETURN" statement (see RETURN) will deliver data read from the file and from which a "WRITE" statement (see WRITE) or "RELEASE" statement (see RELEASE) statement will obtain the data to be written to the file.
  7. The various 01-level record descriptions for a file description implicitly share that one common record buffer (thus, they provide different ways to view the structure of data that can exist within the file). Record buffers can be shared between files by using the "SAME RECORD AREA" (see SAME RECORD AREA) clause.
  8. The only valid level numbers are 01-49, 66, 77, 78 and 88. Level numbers 66, 77, 78 and 88 all have special uses — See Special Data Items, for details.
  9. Not specifying an <identifier-1> or "FILLER" immediately after the level number has the same effect as if "FILLER" were specified. A data item named "FILLER" cannot be referenced directly; these items are generally used to specify an unused portion of the total storage allocated to a group item or to describe a group item whose contents which will only be referenced using the names of those items that belong to it.
  10. "EXTERNAL" cannot be combined with "GLOBAL" or "REDEFINES".
  11. File section data buffers (and therefore all 01-level record layouts defined in the file section) are initialized to all binary zeros when the program is loaded into storage.
  12. See Data Description Clauses, for information on the usage of the various data description clauses.


5.3. WORKING-STORAGE SECTION

WORKING-STORAGE-SECTION-Data-Item Syntax
=======================================================================

 level-number [ identifier-1 | FILLER ] [ IS GLOBAL | EXTERNAL ]
                               ~~~~~~        ~~~~~~   ~~~~~~~~
 [ BASED ]
   ~~~~~
 [ BLANK WHEN ZERO ]
   ~~~~~      ~~~~
 [ JUSTIFIED RIGHT ]
   ~~~~
 [ OCCURS [ integer-1 TO ] integer-2 TIMES
   ~~~~~~             ~~
       [ DEPENDING ON identifier-2 ]
         ~~~~~~~~~
       [ ASCENDING|DESCENDING KEY IS identifier-3 ]
         ~~~~~~~~~ ~~~~~~~~~~
       [ INDEXED BY identifier-4 ] ]
         ~~~~~~~
 [ PICTURE IS picture-string ]
   ~~~
 [ REDEFINES identifier-5 ]
   ~~~~~~~~~
 [ SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ]
   ~~~~    ~~~~~~~ ~~~~~~~~   ~~~~~~~~
 [ SYNCRONIZED|SYNCHRONISED [ LEFT|RIGHT ] ]
   ~~~~        ~~~~           ~~~~ ~~~~~
 [ USAGE IS data-item-usage ]
   ~~~~~
 [ VALUE IS [ ALL ] literal-1 ] . [ WORKING-STORAGE-SECTION-Data-Item ]...
   ~~~~~      ~~~

The "LEFT" and "RIGHT" (SYNCRONIZED) clauses are syntactically recognized but are otherwise non-functional.


=======================================================================
  1. The reserved words "BY", "CHARACTER", "IS", "KEY", "ON", "RIGHT" (JUSTIFIED), "TIMES" and "WHEN" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved words "SYNCRONIZED" and "SYNCHRONISED" are interchangeable. Both may be abbreviated as "SYNC".
  3. The reserved word "PICTURE" may be abbreviated to "PIC".
  4. The reserved word "JUSTIFIED" may be abbreviated to "JUST".
  5. As the syntax diagram shows, the definition of a <<WORKING-STORAGE-SECTION-Data-Item>> is a recursive one in that there may be any number of such specifications coded following one another. The first such specification must have a level number of 01. Specifications that follow that one may have level numbers greater than 01, in which case they are defining a hierarchical breakdown of a record. The definition of a record is terminated when one of the following occurs:
  6. Every <<WORKING-STORAGE-SECTION-Data-Item>> description must be terminated with a period.
  7. The only valid level numbers are 01-49, 66, 77, 78 and 88. Level numbers 01 through 49 are used to define data items that may be part of a hierarchical structure. Level number 01 can also be used to define a constant — an item with an unchangeable value specified at compilation time.
  8. Level numbers 66, 77, 78 and 88 all have special uses — See Special Data Items, for details.
  9. Not specifying an <identifier-1> or "FILLER" immediately after the level number has the same effect as if "FILLER" were specified. A data item named "FILLER" cannot be referenced directly; these items are generally used to specify an unused portion of the total storage allocated to a group item or to describe a group item whose contents which will only be referenced using the names of those items that belong to it.
  10. Data items defined within the working-storage section are automatically initialized once — as the program in which the data is defined is loaded into memory. Subprograms may be loaded into memory more than once (see the "CANCEL" statement (see CANCEL)), in which case initialization will happen each time they are loaded. See Data Initialization, for a discussion of the initialization rules.
  11. See Data Description Clauses, for information on the usage of the various data description clauses.


5.4. LOCAL-STORAGE SECTION

LOCAL-STORAGE-SECTION-Data-Item Syntax
=======================================================================

 level-number [ identifier-1 | FILLER ] [ IS GLOBAL|EXTERNAL ]
                               ~~~~~~        ~~~~~~ ~~~~~~~~
 [ BASED ]
   ~~~~~
 [ BLANK WHEN ZERO ]
   ~~~~~      ~~~~
 [ JUSTIFIED RIGHT ]
   ~~~~
 [ OCCURS [ integer-1 TO ] integer-2 TIMES
   ~~~~~~             ~~
       [ DEPENDING ON identifier-2 ]
         ~~~~~~~~~
       [ ASCENDING|DESCENDING KEY IS identifier-3 ]
         ~~~~~~~~~ ~~~~~~~~~~
       [ INDEXED BY identifier-4 ] ]
         ~~~~~~~
 [ PICTURE IS picture-string ]
   ~~~
 [ REDEFINES identifier-5 ]
   ~~~~~~~~~
 [ SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ]
   ~~~~    ~~~~~~~ ~~~~~~~~   ~~~~~~~~
 [ SYNCRONIZED|SYNCHRONISED [ LEFT|RIGHT ] ]
   ~~~~        ~~~~           ~~~~ ~~~~~
 [ USAGE IS data-item-usage ]
   ~~~~~
 [ VALUE IS [ ALL ] literal-1 ] . [ LOCAL-STORAGE-SECTION-Data-Item ]...
   ~~~~~      ~~~

The "LEFT" and "RIGHT" (SYNCRONIZED) clauses are syntactically recognized but are otherwise non-functional.


=======================================================================
  1. The reserved words "BY", "CHARACTER" "IS", "KEY", "ON", "RIGHT" (JUSTIFIED), "TIMES" and "WHEN" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved words "SYNCRONIZED" and "SYNCHRONISED" are interchangeable. Both may be abbreviated as "SYNC".
  3. The reserved word "PICTURE" may be abbreviated to "PIC".
  4. The reserved word "JUSTIFIED" may be abbreviated to "JUST".
  5. As the syntax diagram shows, the definition of a <<LOCAL-STORAGE-SECTION-Data-Item>> is a recursive one in that there may be any number of such specifications coded following one another. The first such specification must have a level number of 01. Specifications that follow that one may have level numbers greater than 01, in which case they are defining a hierarchical breakdown of a record. The definition of a record is terminated when one of the following occurs:
  6. Every <<LOCAL-STORAGE-SECTION-Data-Item>> description must be terminated with a period.
  7. The only valid level numbers are 01-49, 66, 77, 78 and 88. Level numbers 01 through 49 are used to define data items that may be part of a hierarchical structure. Level number 01 can also be used to define a constant — an item with an unchangeable value specified at compilation time.
  8. Level numbers 66, 77, 78 and 88 all have special uses — See Special Data Items, for details.
  9. Not specifying an <identifier-1> or "FILLER" immediately after the level number has the same effect as if "FILLER" were specified. A data item named "FILLER" cannot be referenced directly; these items are generally used to specify an unused portion of the total storage allocated to a group item or to describe a group item whose contents which will only be referenced using the names of those items that belong to it.
  10. Local-storage cannot be used in nested subprograms.
  11. See Data Description Clauses, for information on the usage of the various data description clauses.


5.5. LINKAGE SECTION

LINKAGE-SECTION-Data-Item Syntax
=======================================================================

 level-number [ identifier-1 | FILLER ] [ IS GLOBAL|EXTERNAL ]
                               ~~~~~~        ~~~~~~ ~~~~~~~~
 [ ANY LENGTH ]
   ~~~ ~~~~~~
 [ BASED ]
   ~~~~~
 [ BLANK WHEN ZERO ]
   ~~~~~      ~~~~
 [ JUSTIFIED RIGHT ]
   ~~~~
 [ OCCURS [ integer-1 TO ] integer-2 TIMES
   ~~~~~~             ~~
       [ DEPENDING ON identifier-3 ]
         ~~~~~~~~~
       [ ASCENDING|DESCENDING KEY IS identifier-4 ]
         ~~~~~~~~~ ~~~~~~~~~~
       [ INDEXED BY identifier-5 ] ]
         ~~~~~~~
 [ PICTURE IS picture-string ]
   ~~~
 [ REDEFINES identifier-6 ]
   ~~~~~~~~~
 [ SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ]
   ~~~~    ~~~~~~~ ~~~~~~~~   ~~~~~~~~
 [ SYNCRONIZED|SYNCHRONISED [ LEFT|RIGHT ] ]
   ~~~~        ~~~~           ~~~~ ~~~~~
 [ USAGE IS data-item-usage ] . [ LINKAGE-SECTION-Data-Item ]...
   ~~~~~

The "LEFT" and "RIGHT" (SYNCRONIZED) clauses are syntactically recognized but are otherwise non-functional.


=======================================================================
  1. The reserved words "BY", "CHARACTER", "IS", "KEY", "ON" and "WHEN" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved words "SYNCRONIZED" and ""SYNCHRONISED"" are interchangeable. Both may be abbreviated as "SYNC".
  3. The reserved word "PICTURE" may be abbreviated to "PIC".
  4. The reserved word "JUSTIFIED" may be abbreviated to "JUST".
  5. As the syntax diagram shows, the definition of a <<LINKAGE-SECTION-Data-Item>> is a recursive one in that there may be any number of such specifications coded following one another. The first such specification must have a level number of 01. Specifications that follow that one may have level numbers greater than 01, in which case they are defining a hierarchical breakdown of a record. The definition of a record is terminated when one of the following occurs:
  6. Every <<LINKAGE-SECTION-Data-Item>> description must be terminated with a period.
  7. The only valid level numbers are 01-49, 66, 77, 78 and 88. Level numbers 01 through 49 are used to define data items that may be part of a hierarchical structure. Level number 01 can also be used to define a constant — an item with an unchangeable value specified at compilation time.
  8. Level numbers 66, 77, 78 and 88 all have special uses — See Special Data Items, for details.
  9. It is expected that:
    1. A linkage section should occur only within a subprogram. The compiler will not prevent its use in a main program, however.
    2. All 01-level data items described within a subprogram’s linkage section should appear in a "PROCEDURE DIVISION USING" (see PROCEDURE DIVISION USING) or as arguments on an "ENTRY" statement.
    3. Each 01-level data item described within a subprogram’s linkage section should correspond to an argument passed on a "CALL" statement (see CALL) or an argument on a function call to the subprogram.
  10. Not specifying an <identifier-1> or "FILLER" immediately after the level number has the same effect as if "FILLER" were specified. A data item named "FILLER" cannot be referenced directly; these items are generally used to specify an unused portion of the total storage allocated to a group item or to describe a group item whose contents which will only be referenced using the names of those items that belong to it. In the linkage section, 01-level data items cannot be named "FILLER".
  11. No storage is allocated for data defined in the linkage section; the data descriptions there are merely defining storage areas that will be passed to the subprogram by a calling program. Therefore, any discussion of the default initialization of such data is irrelevant. It is possible, however, to manually allocate linkage section data items that aren’t subprogram arguments via the "ALLOCATE" statement (see ALLOCATE) statement. In such cases, initialization will take place as per the documentation of that statement.
  12. See Data Description Clauses, for information on the usage of the various data description clauses.


5.6. REPORT SECTION

REPORT SECTION Syntax
=======================================================================

 [ REPORT SECTION.
   ~~~~~~ ~~~~~~~
   { Report-Description [ { Report-Group-Definition } ]... }... ]
   {                      { 01-Level-Constant       }      }
   {                      { 78-Level-Constant       }      }
   { 01-Level-Constant                                     }
   { 78-Level-Constant                                     }

=======================================================================
Report-Description (RD) Syntax
=======================================================================

 RD report-name [ IS GLOBAL ]
 ~~                  ~~~~~~
 [ CODE IS literal-1 | identifier-1 ]
   ~~~~
 [ { CONTROL IS   } { FINAL        }... ]
   { ~~~~~~~      } { ~~~~~        }
   { CONTROLS ARE } { identifier-2 }
     ~~~~~~~~
 [ PAGE [ { LIMIT IS   } ] [ { literal-2    } LINES ]
   ~~~~   { ~~~~~      }     { identifier-3 } ~~~~
          { LIMITS ARE }
            ~~~~~~
       [ literal-3 | identifier-4 COLUMNS|COLS ]
                                  ~~~~~~~ ~~~~
       [ HEADING IS literal-4 | identifier-5 ]
         ~~~~~~~
       [ FIRST DE|DETAIL IS literal-5 | identifier-6 ]
         ~~~~~ ~~ ~~~~~~
       [ LAST CH|{CONTROL HEADING} IS literal-6 | identifier-7 ]
         ~~~~ ~~  ~~~~~~~ ~~~~~~~
       [ LAST DE|DETAIL IS literal-7 | identifier-8 ]
         ~~~~ ~~ ~~~~~~
       [ FOOTING IS literal-8 | identifier-9 ] ] .
         ~~~~~~~

The "CODE IS"


=======================================================================
  1. The reserved words "ARE" and "IS" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The phrases "CONTROL IS" and "CONTROLS ARE" are interchangeable, as are the "PAGE LIMIT" and "PAGE LIMITS" phrases.
  3. The reserved word "LINES" may be abbreviated as "LINE".
  4. The reserved word "COLUMNS" may be abbreviated as "COLS".
  5. Each report referenced on a "REPORT IS" clause (see File/Sort-Description) must be described with a report description ("RD").
  6. See GLOBAL, for information on the "GLOBAL" option.
  7. Please see Report Writer Features, if you have not read it already. This will familiarize you with the Report Writer terminology that will follow.
  8. The following rules pertain to the "PAGE LIMITS"
    1. If no "PAGE LIMITS" clause is specified, the entire report will be generated as if it consists of a single arbitrarily long page.
    2. All literals (<literal-2> through <literal-8>) must be numeric with non-zero positive integer values.
    3. All identifiers (<identifier-2> through <identifier-8>) must be numeric, unedited with non-zero positive integer values.
    4. Any value specified for <literal-2>|<identifier-2> will define the total number of available lines on any report page, not counting any unused margins at the top and/or bottom of the page (defined by the "LINES AT TOP" and "LINES AT BOTTOM" values specified on the "LINAGE" clause of the "FD" this "RD" is linked to — see File/Sort-Description).
    5. Any value specified for <literal-3>|<identifier-3> will be ignored.
    6. The "HEADING"
    7. The "FIRST DETAIL"
    8. The "LAST CONTROL"
    9. The "LAST DETAIL"
    10. The "FOOTING"
    11. The following rules establish default values for the various "PAGE LIMIT" clauses, assuming there is one:
      • "HEADING" — the default is one (1)
      • "FIRST DETAIL" — the HEADING value is used
      • "LAST CONTROL HEADING" — the value from "LAST DETAIL" or, if that is absent, the value from "FOOTING" or, if that too is absent, the value from "PAGE LIMIT"
      • "LAST DETAIL" — the value from "FOOTING" or, if that is absent, the value from "PAGE LIMIT"
      • "FOOTING" — the value from "LAST DETAIL" or, if that is absent, the value from "PAGE LIMIT"
    12. For the values specified on a "PAGE LIMIT" clause to be valid, all of the following must be true:
      • "HEADING" not > "FIRST DETAIL"
      • "FIRST DETAIL" not > "LAST CONTROL HEADING"
      • "LAST CONTROL HEADING" not > "LAST DETAIL"
      • "LAST DETAIL" not > "FOOTING"
  9. The following rules pertain to the "CONTROL"
    1. If there is no "CONTROL" clause, the report will contain no control breaks; this implies that there can be no "CONTROL HEADING" or "CONTROL FOOTING" report groups defined for this "RD".
    2. Include the reserved word "FINAL"
    3. If you specify "FINAL", it must be the first control break named in the "RD".
    4. Any <identifier-9> specifications included on the "CONTROL" clause are referencing data names defined in any data division section except for the report section.
    5. There must be a "CONTROL HEADING" and/or "CONTROL FOOTING" report group defined in the report section for each <identifier-9>.
    6. At execution time:
      • Each time a "GENERATE" statement (see GENERATE) is executed against a detail report group defined for this "RD", the RWCS will check the contents of each <identifier-2> data item; whenever an <identifier-9>’s value has changed since the previous GENERATE, a control break condition will be in effect for that <identifier-2>.
      • Once the list of control breaks has been determined, the "CONTROL FOOTING" for each <identifier-2> having a control break (if any such report group is defined) will be presented.
      • Next, the "CONTROL HEADING" for each <identifier-2> having a control break (if any such report group is defined) will be presented.
      • The "CONTROL FOOTING" and "CONTROL HEADING" report groups will be presented in the sequence in which they are listed on the "CONTROL" clause.
      • Only after this processing has occurred will the detail report group specified on the "GENERATE" be presented.
  10. Each "RD" will have the following allocated for it:
    1. The "PAGE-COUNTER" special register (see Special Registers), which will contain the current report page number.
      • This register will be set to a value of 1 when an "INITIATE" statement (see INITIATE) is executed for the report and will be incremented by 1 each time the RWCS starts a new page of the report.
      • References to "PAGE-COUNTER" within the report section will be implicitly qualified with the name of the report to which the report group referencing the register belongs.
      • References to "PAGE-COUNTER" in the procedure division must be qualified with the appropriate report name if there are multiple "RD"s defined.
    2. The "LINE-COUNTER" special register , which will contain the current line number on the current page.
  11. The "RD" must be followed by at least one 01-level report group definition.


5.6.1. Report Group Definitions

Report-Group-Definition Syntax
=======================================================================

 01 [ identifier-1 ]

 [ LINE NUMBER IS { integer-1 [ [ ON NEXT PAGE ] } ]
   ~~~~           {                  ~~~~ ~~~~   }
                  { +|PLUS integer-1             }
                  {   ~~~~                       }
                  { ON NEXT PAGE                 }
                       ~~~~ ~~~~
 [ NEXT GROUP IS { [ +|PLUS ] integer-2  } ]
   ~~~~ ~~~~~    {     ~~~~              }
                 { NEXT|{NEXT PAGE}|PAGE }
                   ~~~~  ~~~~ ~~~~  ~~~~
 [ TYPE IS { RH|{REPORT HEADING}                      } ]
   ~~~~    { ~~  ~~~~~~ ~~~~~~~                       }
           { PH|{PAGE HEADING}                        }
           { ~~  ~~~~ ~~~~~~~                         }
           { CH|{CONTROL HEADING} FINAL|identifier-2  }
           { ~~  ~~~~~~~ ~~~~~~~  ~~~~~               }
           { DE|DETAIL                                }
           { ~~ ~~~~~~                                }
           { CF|{CONTROL FOOTING} FINAL|identifier-2  }
           { ~~  ~~~~~~~ ~~~~~~~  ~~~~~               }
           { PF|{PAGE FOOTING}                        }
           {  ~~ ~~~~ ~~~~~~~                         }
           { RF|{REPORT FOOTING}                      }
             ~~  ~~~~~~ ~~~~~~~
 . [ REPORT-SECTION-Data-Item ]...

=======================================================================
  1. The reserved words "IS", "NUMBER" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The "RH" and "REPORT HEADING" terms are interchangeable, as are "PH" and "PAGE HEADING", "CH" and "CONTROL HEADING", "DE" and "DETAIL", "CF" and "CONTROL FOOTING", "PF" and "PAGE FOOTING" as well as "RF" and "REPORT FOOTING".
  3. The report group being defined will be a part of the most-recently coded "RD".
  4. The "TYPE" (see TYPE) clause specifies the type of report group being defined.
  5. The level number used for a report group definition must be 01.
  6. The optional <identifier-1> specification assigns a name to this report group so that the group may be referenced either by a GENERATE statement or on a "USE BEFORE REPORTING".
  7. No two report groups in the same report ("RD") may named with the same <identifier-1>. There may, however, be multiple <identifier-1> definitions in different reports. In such instances, references to <identifier-1> must be qualified by the report name.
  8. There may only be one report heading, report footing, final control heading, final control footing, page heading and page footing defined per report.
  9. Report group declarations must be followed by at least one <<REPORT-SECTION-Data-Item>> with a level number in the range 02-49.
  10. See Data Description Clauses, for information on the usage of the various data description clauses.


5.6.2. REPORT SECTION Data Items

REPORT-SECTION-Data-Item Syntax
=======================================================================

 level-number [ identifier-1 ]

 [ BLANK WHEN ZERO ]
   ~~~~~      ~~~~
 [ COLUMN [ { NUMBER IS   } ] [ +|PLUS ] integer-1 ]
   ~~~      { ~~~~~~      }       ~~~~
            { NUMBERS ARE }
              ~~~~~~~
 [ GROUP INDICATE ]
   ~~~~~ ~~~~~~~~
 [ JUSTIFIED RIGHT ]
   ~~~~
 [ LINE NUMBER IS { integer-2 [ [ ON NEXT PAGE ] } ]
   ~~~~           { +|PLUS integer-2 ~~~~ ~~~~   }
                  {   ~~~~                       }
                  { ON NEXT PAGE                 }
                       ~~~~ ~~~~
 [ OCCURS [ integer-3 TO ] integer-4 TIMES
   ~~~~~~             ~~
     [ DEPENDING ON identifier-2 ]
       ~~~~~~~~~
     [ STEP integer-5 ]
       ~~~~
     [ VARYING identifier-3 FROM { identifier-4 } BY { identifier-5 } ]
       ~~~~~~~              ~~~~ { integer-6    } ~~ { integer-7    }
 [ PICTURE IS picture-string ]
   ~~~
 [ PRESENT WHEN condition-name ]
   ~~~~~~~ ~~~~
 [ SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ]
   ~~~~    ~~~~~~~ ~~~~~~~~   ~~~~~~~~
 [ { SOURCE IS literal-1|identifier-6 [ ROUNDED ]                   } ]
   { ~~~~~~                             ~~~~~~~                     }
   { SUM OF { identifier-7 }... [ { RESET ON FINAL|identifier-8 } ] }
   { ~~~    { literal-2    }      { ~~~~~    ~~~~~              }   }
   { VALUE IS [ ALL ] literal-3   { UPON identifier-9           }   }
     ~~~~~      ~~~                 ~~~~
 . [ REPORT-SECTION-Data-Item ]...

=======================================================================
  1. The reserved words "IS", "NUMBER", "OF", "ON", "RIGHT", "TIMES" and "WHEN" (BLANK) are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved word "COLUMN" may be abbreviated as "COL".
  3. The reserved word "JUSTIFIED" may be abbreviated as "JUST".
  4. The reserved word "PICTURE" may be abbreviated as "PIC".
  5. The "SOURCE" (see SOURCE), "SUM" (see SUM) and "VALUE" (see VALUE) clauses, valid only on an elementary item, are mutually-exclusive of each other.
  6. Group items (those without "PICTURE"
  7. See Data Description Clauses, for information on the usage of the various data description clauses.


5.7. SCREEN SECTION

SCREEN-SECTION-Data-Item Syntax
=======================================================================

 level-number [ identifier-1 | FILLER ]
                               ~~~~~~
 [ AUTO | AUTO-SKIP | AUTOTERMINATE ] [ BELL | BEEP ]
   ~~~~   ~~~~~~~~~   ~~~~~~~~~~~~~     ~~~~   ~~~~
 [ BACKGROUND-COLOR|BACKGROUND-COLOUR IS integer-1 | identifier-2 ]
   ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
 [ BLANK LINE|SCREEN ] [ ERASE EOL|EOS ]
   ~~~~~ ~~~~ ~~~~~~     ~~~~~ ~~~ ~~~
 [ BLANK WHEN ZERO ] [ JUSTIFIED RIGHT ]
   ~~~~~      ~~~~     ~~~~
 [ BLINK ] [ HIGHLIGHT | LOWLIGHT ] [ REVERSE-VIDEO ]
   ~~~~~     ~~~~~~~~~   ~~~~~~~~     ~~~~~~~~~~~~~
 [ COLUMN NUMBER IS [ +|PLUS ] integer-2 | identifier-3 ]
   ~~~                  ~~~~
 [ FOREGROUND-COLOR|FOREGROUND-COLOUR IS integer-3 | identifier-4 ]
   ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
 [ { FROM literal-1 | identifier-5 } ]
   { ~~~~                          }
   { TO identifier-5               }
   { ~~                            }
   { USING identifier-5            }
   { ~~~~~                         }
   { VALUE IS [ ALL ] literal-1    }
     ~~~~~      ~~~
 [ FULL | LENGTH-CHECK ] [ REQUIRED | EMPTY-CHECK ] [ SECURE | NO-ECHO ]
   ~~~~   ~~~~~~~~~~~~     ~~~~~~~~   ~~~~~~~~~~~     ~~~~~~   ~~~~~~~
 [ LEFTLINE ] [ OVERLINE ] [ UNDERLINE ]
   ~~~~~~~~     ~~~~~~~~     ~~~~~~~~~
 [ LINE NUMBER IS [ +|PLUS ] integer-4 | identifier-6 ]
   ~~~~               ~~~~
 [ OCCURS integer-5 TIMES ]
   ~~~~~~
 [ PICTURE IS picture-string ]
   ~~~
 [ PROMPT [ CHARACTER IS literal-2 | identifier-7 ]
   ~~~~~~   ~~~~~~~~~
 [ SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ]
   ~~~~    ~~~~~~~ ~~~~~~~~   ~~~~~~~~
 . [ SCREEN-SECTION-Data-Item ]...

=======================================================================
  1. The reserved words "CHARACTER" ("SEPARATE" clause), "IS", "NUMBER", "RIGHT", "TIMES" and "WHEN" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved word "COLUMN" may be abbreviated as "COL".
  3. The reserved word "PICTURE" may be abbreviated as "PIC".
  4. The following sets of reserved words are interchangeable:
  5. Data items defined in the screen section describe input, output or combination screen layouts to be used with "ACCEPT screen-data-item" statement (see ACCEPT screen-data-item) or "DISPLAY screen-data-item" statement (see DISPLAY screen-data-item) statements. These screen layouts may define the entire available screen area or any subset of it.
  6. The term ’available screen area’ is a nebulous one in those environments where command-line shell sessions are invoked within a graphical user-interface environment, as will be the case on Windows, OSX and most Unix/Linux systems — these environments allow command-line session windows to exist with a variable number of available screen rows and columns. When you are designing GnuCOBOL screens, you need to do so with an awareness of the logical screen row/column geometry the program will be executing within.
  7. Data items with level numbers 01 (Constants), 66, 78 and 88 may be used in the screen section; they have the same syntax, rules and usage as they do in the other data division sections.
  8. Without "LINE" (see LINE) or "COLUMN" (see COLUMN) clauses, screen section fields will display on the console window beginning at whatever line/column coordinate is stated or implied by the "ACCEPT screen-data-item" or "DISPLAY screen-data-item" statement that presents the screen item. After a field is presented to the console window, the next field will be presented immediately following that field.
  9. A "LINE" clause explicitly stated in the definition of a screen section data item will override any "LINE" clause included on the "ACCEPT screen-data-item" or "DISPLAY screen-data-item" statement that presents that data item to the screen. The same is true of "COLUMN" clauses.
  10. The Tab and Back-Tab (Shift-Tab on most keyboards) keys will position the cursor from field to field in the line/column sequence in which the fields occur on the screen at execution time, regardless of the sequence in which they were defined in the screen section.
  11. See Data Description Clauses, for information on the usage of the various data description clauses.


5.8. Special Data Items



5.8.1. 01-Level Constants

01-Level-Constant Syntax
=======================================================================

 01 constant-name-1 CONSTANT [ IS GLOBAL ]
                    ~~~~~~~~      ~~~~~~
   { AS { literal-1                           } } .
   {    { { BYTE-LENGTH } OF { identifier-1 } } }
   {    { { ~~~~~~~~~~~ }    { usage-name   } } }
   {    { { LENGTH      }                     } }
   {        ~~~~~~                              }
   { FROM CDF-variable-name-1                   }
     ~~~~

=======================================================================
This syntax is valid in the following sections:
FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, SCREEN

The 01-level constant is one of four types of compilation-time constants that can be declared within a program. The other three types are ">>DEFINE" CDF directive (see >>DEFINE) constants, ">>SET" CDF directive (see >>SET) constants and 78-level constants (see 78-Level Data Items).

  1. The reserved words "AS", "IS" and "OF" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. See GLOBAL, for information on the "GLOBAL" option.
  3. This particular type of constant declaration provides the ability to determine the length of a data item or the storage size associated with a particular numeric "USAGE" (see USAGE) type — something not possible with the other types of constants.
  4. Constants defined in this way become undefined once an "END PROGRAM" or "END FUNCTION" is encountered in the input source.
  5. Data descriptions of this form do not actually allocate any storage — they merely define a name (<constant-name-1>) that may be used anywhere a numeric literal ("BYTE-LENGTH"
  6. The <constant-name-1> name may not be referenced on a CDF directive.
  7. Care must be taken that <constant-name-1> does not duplicate any other data item name that has been defined in the program as references to that data item name will refer to the constant and not the data item. The GnuCOBOL compiler will not issue a warning about this condition.
  8. The value specified for <usage-name> may be any "USAGE" that does not use a "PICTURE" (see PICTURE) clause. These would be any of "BINARY-C-LONG", "BINARY-CHAR", "BINARY-DOUBLE", "BINARY-LONG", "BINARY-SHORT", "COMP-1" (or "COMPUTATIONAL-1"), "COMP-2" (or "COMPUTATIONAL-2"), "FLOAT-DECIMAL-16", "FLOAT-DECIMAL-34", "FLOAT-LONG", "FLOAT-SHORT", "POINTER", or "PROGRAM-POINTER".
  9. The "BYTE-LENGTH" clause will produce a numeric value for <constant-name-1> identical to that which would be returned by the "BYTE-LENGTH" intrinsic function executed against <identifier-1> or a data item declared with a "USAGE" of <usage-name>.
  10. The "LENGTH" clause will produce a numeric value for <constant-name-1> identical to that which would be returned by the "LENGTH" intrinsic function executed against <identifier-1> or a data item declared with a "USAGE" of <usage-name>.

Here is the listing of a GnuCOBOL program that uses 01-level constants to display the length (in bytes) of the various picture-less usage types.

    IDENTIFICATION DIVISION.
    PROGRAM-ID. Usage Lengths.
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    01  Len-BINARY-C-LONG    CONSTANT AS LENGTH OF BINARY-C-LONG.
    01  Len-BINARY-CHAR      CONSTANT AS LENGTH OF BINARY-CHAR.
    01  Len-BINARY-DOUBLE    CONSTANT AS LENGTH OF BINARY-DOUBLE.
    01  Len-BINARY-LONG      CONSTANT AS LENGTH OF BINARY-LONG.
    01  Len-BINARY-SHORT     CONSTANT AS LENGTH OF BINARY-SHORT.
    01  Len-COMP-1           CONSTANT AS LENGTH OF COMP-1.
    01  Len-COMP-2           CONSTANT AS LENGTH OF COMP-2.
    01  Len-FLOAT-DECIMAL-16 CONSTANT AS LENGTH OF FLOAT-DECIMAL-16.
    01  Len-FLOAT-DECIMAL-34 CONSTANT AS LENGTH OF FLOAT-DECIMAL-34.
    01  Len-FLOAT-LONG       CONSTANT AS LENGTH OF FLOAT-LONG.
    01  Len-FLOAT-SHORT      CONSTANT AS LENGTH OF FLOAT-SHORT.
    01  Len-POINTER          CONSTANT AS LENGTH OF POINTER.
    01  Len-PROGRAM-POINTER  CONSTANT AS LENGTH OF PROGRAM-POINTER.
    PROCEDURE DIVISION.
    000-Main.
        DISPLAY "On this system, with this build of GnuCOBOL, the"
        DISPLAY "PICTURE-less USAGE's have these lengths (in bytes):"
        DISPLAY " "
        DISPLAY "BINARY-C-LONG:    " Len-BINARY-C-LONG
        DISPLAY "BINARY-CHAR:      " Len-BINARY-CHAR
        DISPLAY "BINARY-DOUBLE:    " Len-BINARY-DOUBLE
        DISPLAY "BINARY-LONG:      " Len-BINARY-LONG
        DISPLAY "BINARY-SHORT:     " Len-BINARY-SHORT
        DISPLAY "COMP-1:           " Len-COMP-1
        DISPLAY "COMP-2:           " Len-COMP-2
        DISPLAY "FLOAT-DECIMAL-16: " Len-FLOAT-DECIMAL-16
        DISPLAY "FLOAT-DECIMAL-34: " Len-FLOAT-DECIMAL-34
        DISPLAY "FLOAT-LONG:       " Len-FLOAT-LONG
        DISPLAY "FLOAT-SHORT:      " Len-FLOAT-SHORT
        DISPLAY "POINTER:          " Len-POINTER
        DISPLAY "PROGRAM-POINTER:  " Len-PROGRAM-POINTER
        STOP RUN
        .

The output of this program, on a Windows 7 system with a 32-bit MinGW build of GnuCOBOL is:

    On this system, with this build of GnuCOBOL, the
    PICTURE-less USAGE's have these lengths (in bytes):

    BINARY-C-LONG:    4
    BINARY-CHAR:      1
    BINARY-DOUBLE:    8
    BINARY-LONG:      4
    BINARY-SHORT:     2
    COMP-1:           4
    COMP-2:           8
    FLOAT-DECIMAL-16: 8
    FLOAT-DECIMAL-34: 16
    FLOAT-LONG:       8
    FLOAT-SHORT:      4
    POINTER:          4
    PROGRAM-POINTER:  4


5.8.2. 66-Level Data Items

66-Level-Data-Item Syntax
=======================================================================

 66 identifier-1 RENAMES identifier-2 [ THRU|THROUGH identifier-3 ] .
                 ~~~~~~~                ~~~~ ~~~~~~~

=======================================================================
This syntax is valid in the following sections:
FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE

A 66-level data item regroups previously defined items by specifying alternative, possibly overlapping, groupings of elementary data items.

  1. The reserved words "THRU" and "THROUGH" are interchangeable.
  2. A level-66 data item cannot rename a level-66, level-01, level-77, or level-88 data item.
  3. There may be multiple level-66 data items that rename data items contained within the same 01-level record description.
  4. All "RENAMES" entries associated with one logical record must immediately follow that record’s last data description entry.


5.8.3. 77-Level Data Items

77-Level-Data-Item Syntax
=======================================================================

 77 identifier-1 [ IS GLOBAL|EXTERNAL ]
                      ~~~~~~ ~~~~~~~~
 [ BASED ]
   ~~~~~
 [ BLANK WHEN ZERO ]
   ~~~~~      ~~~~
 [ JUSTIFIED RIGHT ]
   ~~~~
 [ PICTURE IS picture-string ]
   ~~~
 [ REDEFINES identifier-5 ]
   ~~~~~~~~~
 [ SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ]
   ~~~~    ~~~~~~~ ~~~~~~~~   ~~~~~~~~
 [ SYNCRONIZED|SYNCHRONISED [ LEFT|RIGHT ] ]
   ~~~~        ~~~~           ~~~~ ~~~~~
 [ USAGE IS data-item-usage ]
   ~~~~~
 [ VALUE IS [ ALL ] literal-1 ] .
   ~~~~~      ~~~

The "LEFT" and "RIGHT" (SYNCRONIZED) clauses are syntactically recognized but are otherwise non-functional.


=======================================================================
This syntax is valid in the following sections:
WORKING-STORAGE, LOCAL-STORAGE, LINKAGE

The intent of a 77-level item is to be able to create a stand-alone elementary data item.

  1. The reserved words "CHARACTER", "IS", "RIGHT" (JUSTIFIED) and "WHEN" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved word "JUSTIFIED" may be abbreviated as "JUST", the reserved word "PICTURE" may be abbreviated as "PIC" and the reserved words "SYNCRONIZED" and "SYNCHRONISED" may be abbreviated as "SYNC".
  3. New programs requiring a stand-alone elementary item should be coded to use a level number of 01 rather than 77.
  4. See Data Description Clauses, for information on the usage of the various data description clauses.


5.8.4. 78-Level Data Items

78-Level-Constant Syntax
=======================================================================

 78 constant-name-1 VALUE IS literal-1 .
                    ~~~~~

=======================================================================
This syntax is valid in the following sections:
FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, SCREEN

The 78-level constant is one of four types of compilation-time constants that can be declared within a program. The other three types are ">>DEFINE" CDF directive (see >>DEFINE) constants, ">>SET" CDF directive (see >>SET) constants and 01-level constants (see 01-Level Constants).

  1. The reserved word "IS" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. Constants defined in this way become undefined once an "END PROGRAM" or "END FUNCTION" is encountered in the input source.
  3. Data descriptions of this form do not actually allocate any storage — they merely define a name (<constant-name-1>) that may be used anywhere a literal of the same type as <literal-1> may be used.
  4. The <constant-name-1> name may not be referenced on a CDF directive.
  5. Care must be taken that <constant-name-1> does not duplicate any other data item name that has been defined in the program as references to that data item name will refer to the constant and not the data item. The GnuCOBOL compiler will not issue a warning about this condition.


5.8.5. 88-Level Data Items

88-Level-Data-Item Syntax
=======================================================================

 88 condition-name-1 { VALUE IS   } {literal-1 [ THRU|THROUGH literal-2 ]}...
                     { ~~~~~      }              ~~~~ ~~~~~~~
                     { VALUES ARE }
                       ~~~~~~

   [ WHEN SET TO FALSE IS literal-3 ] .
                 ~~~~~

=======================================================================
This syntax is valid in the following sections:
FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT, SCREEN

Condition names are Boolean (i.e. TRUE / FALSE) data items that receive their TRUE and FALSE values based upon the values of the non 88-level data item whose definition they immediately follow.

  1. The reserved words "ARE", "IS", "SET" and "TO" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved words "THRU" and "THROUGH" are interchangeable.
  3. Condition names are always defined subordinate to another (non 88-level) data item. That data item must be an elementary item. Whenever the parent data item assumes one of the values specified on the 88-level item’s "VALUE" (see VALUE) clause, <condition-name-1> will take on the value of TRUE.
  4. Condition names do not occupy any storage.
  5. The optional "THROUGH" clause allows a range of possible TRUE values to be specified.
  6. Whenever the parent data item assumes any value except one of the values specified on <condition-name-1>’s "VALUE" clause, <condition-name-1> will take on the value of FALSE.
  7. Executing the statement "SET <condition-name-1> TO TRUE" will cause <condition-name-1>’s parent data item to take on the first value specified on <condition-name-1>’s "VALUE" clause.
  8. Executing the statement "SET <condition-name-1> TO FALSE" will cause <condition-name-1>’s parent data item to take on the value specified on <condition-name-1>’s "FALSE" clause. If <condition-name-1> does not have a "FALSE" clause, the "SET" (see SET) statement will generate an error message at compilation time.
  9. See Condition Names, for more information.


5.9. Data Description Clauses



5.9.1. ANY LENGTH

ANY LENGTH Attribute Syntax
=======================================================================

 ANY LENGTH
 ~~~ ~~~~~~

=======================================================================
This syntax is valid in the following sections:
LINKAGE

Data items declared with the "ANY LENGTH" attribute have no fixed compile-time length. Such items may only be defined in the linkage section of a subprogram as they may only serve as subroutine argument descriptions. These items must have a "PICTURE" (see PICTURE) clause that specifies exactly one A, X or 9 symbol.

  1. The "ANY LENGTH" and "BASED" (see BASED) clauses cannot be used together in the same data item description.


5.9.2. AUTO

AUTO Attribute Syntax
=======================================================================

 AUTO
 ~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

A field whose description includes this attribute will cause the cursor to automatically advance to the next input-enabled field of a screen if the field is completely filled with input data.

  1. The "AUTO", "AUTO-SKIP" (see AUTO-SKIP) and "AUTOTERMINATE" (see AUTOTERMINATE) clauses are interchangeable, and may not be used together in the same data item description.


5.9.3. AUTO-SKIP

AUTO-SKIP Attribute Syntax
=======================================================================

 AUTO-SKIP
 ~~~~~~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

A field whose description includes this attribute will cause the cursor to automatically advance to the next input-enabled field of a screen if the field is completely filled with input data.

  1. The "AUTO" (see AUTO), "AUTO-SKIP" and "AUTOTERMINATE" (see AUTOTERMINATE) clauses are interchangeable, and may not be used together in the same data item description.


5.9.4. AUTOTERMINATE

AUTOTERMINATE Attribute Syntax
=======================================================================

 AUTOTERMINATE
 ~~~~~~~~~~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

A field whose description includes this attribute will cause the cursor to automatically advance to the next input-enabled field of a screen if the field is completely filled with input data.

  1. The "AUTO" (see AUTO), "AUTO-SKIP" (see AUTO-SKIP) and "AUTOTERMINATE" clauses are interchangeable, and may not be used together in the same data item description.


5.9.5. BACKGROUND-COLOR

BACKGROUND-COLOR Attribute Syntax
=======================================================================

 BACKGROUND-COLOR|BACKGROUND-COLOUR IS integer-1 | identifier-1
 ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

This clause is used to specify the screen background color of the screen data item or the default screen background color of subordinate items if used on a group item.

  1. The reserved word "IS" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. The reserved words "BACKGROUND-COLOR" and "BACKGROUND-COLOUR" are interchangeable.
  3. You specify colors by number (0-7), or by using the constant names provided in the "screenio.cpy" copybook (which is provided with all GnuCOBOL source distributions).
  4. Colors may also be specified using a numeric non-edited identifier whose value is in the range 0-7.

See Color Palette and Video Attributes, for more information on screen colors and video attributes.



5.9.6. BASED

BASED Attribute Syntax
=======================================================================

 BASED
 ~~~~~

=======================================================================
This syntax is valid in the following sections:
WORKING-STORAGE, LOCAL-STORAGE, LINKAGE

Data items declared with "BASED" are allocated no storage at compilation time. At run-time, the "ALLOCATE" (see ALLOCATE) or "SET ADDRESS" (see SET ADDRESS) statements are used to allocate space for and (optionally) initialize such items.

  1. The "BASED" and "ANY LENGTH" (see ANY LENGTH) clauses cannot be used together in the same data item description.
  2. The "BASED" clause may only be used on level 01 and level 77 data items.


5.9.7. BEEP

BEEP Attribute Syntax
=======================================================================

 BEEP
 ~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN
  1. The "BEEP" and "BELL" (see BELL) clauses are interchangeable, and may not be used together in the same data item description.
  2. Use this clause to cause an audible tone to occur when the screen item is DISPLAYed.


5.9.8. BELL

BELL Attribute Syntax
=======================================================================

 BELL
 ~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN
  1. The "BEEP" (see BEEP) and "BELL" clauses are interchangeable, and may not be used together in the same data item description.
  2. Use this clause to cause an audible tone to occur when the screen item is DISPLAYed.


5.9.9. BLANK

BLANK Attribute Syntax
=======================================================================

 BLANK LINE|SCREEN
 ~~~~~ ~~~~ ~~~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

This clause will blank out either the entire screen (BLANK SCREEN) or just the line upon which data is about to be displayed (BLANK LINE).

  1. Blanked-out areas will have their foreground and background colors set to the attributes of the field containing the "BLANK" clause.
  2. This clause is useful when one screen section item is being displayed over the top of a previously-displayed one.


5.9.10. BLANK WHEN ZERO

BLANK-WHEN-ZERO Attribute Syntax
=======================================================================

 BLANK WHEN ZERO
 ~~~~~      ~~~~

=======================================================================
This syntax is valid in the following sections:
FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT, SCREEN

This clause will cause that item’s value to be automatically transformed into spaces if a value of 0 is ever MOVEd to the item.

  1. The reserved word "WHEN" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. This clause may only be used on a PIC 9 data item with a "USAGE" (see USAGE) of "DISPLAY".


5.9.11. BLINK

BLINK Attribute Syntax
=======================================================================

 BLINK
 ~~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

The "BLINK" clause modifies the visual appearance of the displayed field by making the field contents blink.

See Color Palette and Video Attributes, for more information on screen colors and video attributes.



5.9.12. COLUMN

COLUMN (REPORT SECTION) Clause Syntax
=======================================================================

 COLUMN [ { NUMBER IS   } ] [ +|PLUS ] integer-1 ]
 ~~~      { NUMBERS ARE }       ~~~~

=======================================================================
COLUMN (SCREEN SECTION) Clause Syntax
=======================================================================

 COLUMN NUMBER IS [ +|PLUS ] integer-2 | identifier-3 ]
 ~~~                  ~~~~

=======================================================================
This syntax is valid in the following sections:
REPORT, SCREEN

The "COLUMN" clause provides the means of stating in which column a field should be presented on the console window (screen section) or a report (report section).

  1. The reserved words "ARE", "IS", "NUMBER" and "NUMBERS" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved word "COLUMN" may be abbreviated as "COL".
  3. The line location of a report section or screen section field will be determined by the "LINE" (see LINE) clause.
  4. The value of <integer-1> must be 1 or greater.
  5. If <identifier-1> is used to specify either an absolute or relative column position, <identifier-1> must be defined as a numeric item of any "USAGE" (see USAGE) other than "COMPUTATIONAL-1" or "COMPUTATIONAL-2", without editing symbols. The value of <identifier-1> at the time the screen data item is presented must be 1 or greater. Note that a "COMPUTATIONAL-1" or "COMPUTATIONAL-2" identifier will be accepted by the compiler, but will produce unpredictable results at run-time.
  6. The column coordinate of a field may be stated on an absolute basis (i.e. "COLUMN 5") or on a relative basis based upon the end of the previously-presented field (i.e. "COLUMN PLUS 1").
  7. The symbol "+" may be used in lieu of the word "PLUS", if desired; if symbol "+" is used, however, there must be at least one space separating it from <integer-1>. Failure to include this space will cause the symbol "+" sign to be simply treated as part of <integer-1> and will treat the "COLUMN" clause as an absolute column specification rather than a relative one.
  8. Using relative column positioning ("COLUMN PLUS") has slightly different behaviour depending upon the section in which the clause is used, as follows:
    1. When used on a report section data item, "COLUMN PLUS" will position the start of the new field’s value such that there are <integer-1> blank columns between the end of the previous field and the beginning of this field.

      If a report data item’s description includes the "SOURCE" (see SOURCE), "SUM" (see SUM) or "VALUE" (see VALUE) clause but has no "COLUMN" clause, "COLUMN PLUS 1" will be assumed.

    2. When used on a screen section data item, "COLUMN PLUS" will position the new field so that it begins exactly <integer-1> or <identifier-1> characters past the last character of the previous field. Thus, "COLUMN PLUS 1" will leave no blank positions between the end of the previous field and the start of this one.

      If a screen data item’s description includes the "FROM" (see FROM), "TO" (see TO), "USING" (see USING) or "VALUE" (see VALUE) clause but has no "COLUMN" clause, the new screen field will begin at the column coordinate of the last character of the previous field.



5.9.13. CONSTANT

CONSTANT Attribute Syntax
=======================================================================

 CONSTANT
 ~~~~~~~~

=======================================================================
This syntax is valid in the following sections:
FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, SCREEN

This option signifies that the 01-level data item in whose declaration "CONSTANT" is specified will be treated as a symbolic name for a literal value, usable wherever a literal of the appropriate type could be used.

  1. The value of a data item defined as a constant cannot be changed at run-time. In fact, it is not syntactically acceptable to use such a data item as the destination field of any procedure division statement that stores a value.
  2. See 01-Level Constants, for additional information.


5.9.14. EMPTY-CHECK

EMPTY-CHECK Attribute Syntax
=======================================================================

 EMPTY-CHECK
 ~~~~~~~~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

This clause forces the user to enter data into the field it is specified on (or into all subordinate input-capable fields if "EMPTY-CHECK" is specified on a group item).

  1. The "EMPTY-CHECK" and "REQUIRED" (see REQUIRED) clauses are interchangeable, and may not be used together in the same data item description.
  2. In order to take effect, the user must first move the cursor into the field having this clause in its definition.
  3. The "ACCEPT screen-data-item" statement (see ACCEPT screen-data-item) will ignore the Enter key and any other cursor-moving keystrokes that would cause the cursor to move to another screen item unless data has been entered into the field. Function keys will still be allowed to terminate the "ACCEPT".
  4. In order to be functional, this attribute must be supported by the underlying ’curses’ package your GnuCOBOL implementation was built with. As of this time, the ’PDCurses’ package (used for native Windows or MinGW builds) does not support "EMPTY-CHECK".


5.9.15. ERASE

ERASE Clause Syntax
=======================================================================

 ERASE EOL|EOS
 ~~~~~ ~~~ ~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

"ERASE" will blank-out screen contents from the location where the screen data item whose description contains this clause will be displayed, forward until the end of the screen ("ERASE EOS")

  1. Erased areas will have their foreground and background colors set to the attributes of the field containing the "ERASE" clause.
  2. This clause is useful when one screen section item is being displayed over the top of a previously-displayed one.

See Color Palette and Video Attributes, for more information on screen colors and video attributes.



5.9.16. EXTERNAL

EXTERNAL Attribute Syntax
=======================================================================

 EXTERNAL
 ~~~~~~~~

=======================================================================
This syntax is valid in the following sections:
FILE, WORKING-STORAGE, LOCAL-STORAGE

This clause marks a data item description, "FD" or "SD" see File/Sort-Description as being shareable with other programs executed from the same execution thread.

  1. By specifying the "EXTERNAL" clause on either an FD or an SD, the file description is capable of being shared between all programs executed from the same execution thread, provided an "EXTERNAL" clause is coded with the file’s description in each program requiring it. This sharing allows the file to be opened, read and/or written and closed in different programs. This sharing applies to the record descriptions subordinate to the file description too.
  2. By specifying the "EXTERNAL" clause on the description of a data item, the data item is capable of being shared between all programs executed from the same execution thread, provided the data item is coded (with an "EXTERNAL" clause) in each program requiring it.
  3. The following points apply to the specification of "EXTERNAL" in a data item’s definition:
    1. The "EXTERNAL" clause may only be specified at the 77 or 01 level.
    2. An "EXTERNAL" item must have a data name and that name cannot be "FILLER".
    3. "EXTERNAL" cannot be combined with "BASED" (see BASED), "GLOBAL" (see GLOBAL) or "REDEFINES" (see REDEFINES).


5.9.17. FALSE

FALSE Clause Syntax
=======================================================================

 WHEN SET TO FALSE IS literal-1
             ~~~~~

=======================================================================
This syntax is valid in the following sections:
FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT, SCREEN

This clause, which may only appear on the definition of a level-88 condition name, is used to specify the value of the data item that serves as the parent of the level-88 condition name that will force the condition name to assume a value of FALSE.

  1. The reserved words "IS", "SET", "TO" and "WHEN" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. See 88-Level Data Items, or See Condition Names, for more information.


5.9.18. FOREGROUND-COLOR

FOREGROUND-COLOR Attribute Syntax
=======================================================================

 FOREGROUND-COLOR|FOREGROUND-COLOUR IS integer-1 | identifier-1
 ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

This clause is used to specify the color of text within a screen data item or the default text color of subordinate items if used on a group item.

  1. The reserved word "IS" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. The reserved words "FOREGROUND-COLOR" and "FOREGROUND-COLOUR" are interchangeable.
  3. You specify colors by number (0-7), or by using the constant names provided in the "screenio.cpy" copybook (which is provided with all GnuCOBOL source distributions).
  4. Colors may also be specified using a numeric non-edited identifier whose value is in the range 0-7.

See Color Palette and Video Attributes, for more information on screen colors and video attributes.



5.9.19. FROM

FROM Clause Syntax
=======================================================================

 FROM literal-1 | identifier-5
 ~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

This clause is used to specify either the data item a screen section field is to obtain it’s value from when the screen is displayed, or a literal that will specify the value of that same field.

  1. The "FROM", "TO" (see TO), "USING" (see USING) and "VALUE" (see VALUE) clauses are mutually-exclusive in any screen section data item’s definition.


5.9.20. FULL

FULL Attribute Syntax
=======================================================================

 FULL
 ~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

The "FULL" clause forces the user to enter data into the field it is specified on (or into all subordinate input-capable fields if specified on a group item) sufficient to fill every character position of the field.

  1. The "FULL" and "LENGTH-CHECK" (see LENGTH-CHECK) clauses are interchangeable, and may not be used together in the same data item description.
  2. In order for this clause to take effect at execution time, the user must move the cursor into the field having this clause in its definition.
  3. The "ACCEPT screen-data-item" statement (see ACCEPT screen-data-item) will ignore the Enter key and any other cursor-moving keystrokes that would cause the cursor to move to another screen item unless the proper amount of data has been entered into the field. Function keys will still be allowed to terminate the "ACCEPT", however.
  4. In order to be functional, this attribute must be supported by the underlying ’curses’ package your GnuCOBOL implementation was built with. As of this time, the ’PDCurses’ package (used for native Windows or MinGW builds) does not support "FULL".


5.9.21. GLOBAL

GLOBAL Attribute Syntax
=======================================================================

 GLOBAL
 ~~~~~~

=======================================================================
This syntax is valid in the following sections:
FILE, WORKING-STORAGE, LOCAL-STORAGE, REPORT

This clause marks a data item, 01-level constant, "FD" (see File/Sort-Description), "SD" (see File/Sort-Description) or an "RD" (see REPORT SECTION) as being shareable with any nested subprograms.

  1. By specifying the "GLOBAL" clause on the description of a file or a report, that description is capable of being shared between a program and any nested subprograms within it, provided the "FD", "SD" or "RD" is coded (with a "GLOBAL" clause) in each nested subprogram requiring it. This sharing allows the file to be opened, read and/or written and closed or the report to be initiated or terminated in those programs. Separately compiled programs may not share a "GLOBAL" file description, but they may share an "EXTERNAL" (see EXTERNAL) file description. This sharing applies to the record descriptions subordinate to the file description and the report groups subordinate to the "RD" also.
  2. By specifying the "GLOBAL" clause on the description of a data item, the data item is capable of being shared between a program and any nested subprograms within it, provided the data item is coded (with a "GLOBAL" clause) in each program requiring it.
  3. The following points apply to the specification of "GLOBAL" in a data item’s definition:
    1. The "GLOBAL" clause may only be specified at the 77 or 01 level.
    2. A "GLOBAL" item must have a data name and that name cannot be "FILLER".
    3. "GLOBAL" cannot be combined with "EXTERNAL" (see EXTERNAL), "REDEFINES" (see REDEFINES) or "BASED" (see BASED).


5.9.22. GROUP INDICATE

GROUP-INDICATE Attribute Syntax
=======================================================================

 GROUP INDICATE
 ~~~~~ ~~~~~~~~

=======================================================================
This syntax is valid in the following sections:
REPORT

The "GROUP INDICATE" clause specifies that the data item in whose definition the clause appears will be presented only in very limited circumstances.

  1. This clause may only appear within a "DETAIL" report group (see TYPE).
  2. When this clause is present, the data item in question will be presented only under the following circumstances:
    1. On the first presentation of the detail group following the "INITIATE" (see INITIATE) of the report.
    2. On the first presentation of the detail group after every new page is started.
    3. On the first presentation of the detail group after any control break occurs.


5.9.23. HIGHLIGHT

HIGHLIGHT Attribute Syntax
=======================================================================

 HIGHLIGHT
 ~~~~~~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

This clause controls the intensity of text ("FOREGROUND-COLOR" (see FOREGROUND-COLOR)) by setting that intensity to its highest of three possible settings.

  1. This clause, along with "LOWLIGHT" (see LOWLIGHT), are intended to provide a three-level intensity scheme ("LOWLIGHT" … nothing (Normal) … "HIGHLIGHT").

See Color Palette and Video Attributes, for more information on screen colors and video attributes.



5.9.24. JUSTIFIED

JUSTIFIED Attribute Syntax
=======================================================================

 JUSTIFIED RIGHT
 ~~~~


=======================================================================
This syntax is valid in the following sections:
FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT, SCREEN

The presence of a "JUSTIFIED RIGHT" clause in a data item’s definition alters the manner in which data is stored into the field from the default ’left-justified, space filled’ behaviour to ’right justified, space filled’.

  1. The reserved word "RIGHT" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. The reserved word "JUSTIFIED" may be abbreviated as "JUST".
  3. This clause is valid only on alphabetic (PIC A) or alphanumeric (PIC X) data items.
  4. The presence or absence of this clause influences the behaviour of the "MOVE" (see MOVE) statement as well as the "FROM" (see FROM), "SOURCE" (see SOURCE) and "USING" (see USING) data item description clauses.
  5. If the value being stored into the field is the same length as the receiving field, the presence or absence of the "JUSTIFIED RIGHT" clause on that field’s description is irrelevant.
  6. The following examples illustrate the behaviour of the presence and absence of the "JUSTIFIED RIGHT" clause when the field size is different than that of the value being stored. In these examples, the symbol b represents a space.
    When the value is shorter than the field size...
    Without JUSTIFIEDWith JUSTIFIED
    01 A PIC X(6).01 A PIC X(6) JUSTIFIED RIGHT.
    MOVE "ABC" TO AMOVE "ABC" TO A
    Result is ’ABCbbbResult is ’bbbABC’

    When the value is longer than the field size...
    Without JUSTIFIEDWith JUSTIFIED
    01 A PIC X(6).01 A PIC X(6) JUSTIFIED RIGHT.
    MOVE "ABCDEFGHI" TO AMOVE "ABCDEFGHI" TO A
    Result is ’ABCDEF’Result is ’DEFGHI’


5.9.25. LEFTLINE

LEFTLINE Attribute Syntax
=======================================================================

 LEFTLINE
 ~~~~~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

The "LEFTLINE" clause will introduce a vertical line at the left edge of a screen field.

  1. The "LEFTLINE", "OVERLINE" (see OVERLINE) and "UNDERLINE" (see UNDERLINE) clauses may be used in any combination in a single field’s description.
  2. This clause is essentially non-functional when used within Windows command shell (cmd.exe) environments and running programs compiled using a GnuCOBOL implementation built using ’PDCurses’ (such as Windows/MinGW builds).
  3. Whether or not this clause operates on Cygwin or UNIX/Linux/OSX systems will depend upon the video attribute capabilities of the terminal output drivers and ’curses’ software being used.

See Color Palette and Video Attributes, for more information on screen colors and video attributes.



5.9.26. LENGTH-CHECK

LENGTH-CHECK Attribute Syntax
=======================================================================

 LENGTH-CHECK
 ~~~~~~~~~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

The "LENGTH-CHECK" clause forces the user to enter data into the field it is specified on (or into all subordinate input-capable fields if specified on a group item) sufficient to fill every character position of the field.

  1. The "FULL" (see FULL) and "LENGTH-CHECK" clauses are interchangeable, and may not be used together in the same data item description.
  2. In order for this clause to take effect at execution time, the user must move the cursor into the field having this clause in its definition.
  3. The "ACCEPT screen-data-item" statement (see ACCEPT screen-data-item) will ignore the Enter key and any other cursor-moving keystrokes that would cause the cursor to move to another screen item unless the proper amount of data has been entered into the field. Function keys will still be allowed to terminate the "ACCEPT", however.
  4. In order to be functional, this attribute must be supported by the underlying ’curses’ package your GnuCOBOL implementation was built with. As of this time, the ’PDCurses’ package (used for native Windows or MinGW builds) does not support "LENGTH-CHECK".


5.9.27. LINE

LINE (REPORT SECTION) Clause Syntax
=======================================================================

 LINE NUMBER IS { integer-2 [ [ ON NEXT PAGE ] }
 ~~~~           {                  ~~~~ ~~~~   }
                { +|PLUS integer-2             }
                {   ~~~~                       }
                { ON NEXT PAGE                 }
                     ~~~~ ~~~~

=======================================================================
LINE (SCREEN SECTION) Clause Syntax
=======================================================================

 [ LINE NUMBER IS [ +|PLUS ] integer-4 | identifier-6 ]
   ~~~~               ~~~~

=======================================================================
This syntax is valid in the following sections:
REPORT, SCREEN

This clause provides a means of explicitly stating on which line a field should be presented on the console window (screen section) or on a report (report section).

  1. The reserved words "IS", "NUMBER" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The following points document the use of format 1 of the "LINE" clause:
    1. The column location of a report item will be determined by the "COLUMN" (see COLUMN) clause.
    2. The value of <integer-1> must be 1 or greater.
    3. The report line number upon which the data item containing this clause along with any subordinate data items will be presented may be stated on an absolute basis (i.e. "LINE 5") or on a relative basis based upon the previously-displayed line (i.e. "LINE PLUS 1").
    4. The symbol "+" may be used in lieu of the word "PLUS", if desired; if "+" is used, however, there must be at least one space separating it from <integer-1>. Failure to include this space will cause the "+" to be simply treated as part of <integer-1> and will treat the LINE clause as an absolute line specification rather than a relative one.
    5. The optional "NEXT PAGE"
  3. The following points document the use for format 2 of the "LINE" clause:
    1. The column location of a screen section field is determined by the "COLUMN" (see COLUMN) clause.
    2. The value of <integer-1> must be 1 or greater.
    3. If <identifier-1> is used to specify either an absolute or relative column position, <identifier-1> must be defined as a numeric item of any "USAGE" (see USAGE) other than "COMPUTATIONAL-1" or "COMPUTATIONAL-2", without editing symbols. The value of <identifier-1> at the time the screen data item is presented must be 1 or greater. Note that a "COMPUTATIONAL-1" or "COMPUTATIONAL-2" identifier will be accepted by the compiler, but will produce unpredictable results at run-time.
    4. The screen line number upon which the data item containing this clause along with any subordinate data items will be displayed may be stated on an absolute basis (i.e. "LINE 5") or on a relative basis based upon the previously-displayed line (i.e. "LINE PLUS 1").
    5. The symbol "+" may be used in lieu of the word "PLUS", if desired; if "+" is used, however, there must be at least one space separating it from <integer-1>. Failure to include this space will cause the "+" to be simply treated as part of <integer-1> and will treat the "LINE" clause as an absolute line specification rather than a relative one.
    6. If a screen data item’s description includes the "FROM" (see FROM), "TO" (see TO), "USING" (see USING) or "VALUE" (see VALUE) clause but has no LINE clause, the "current screen line" will be assumed.


5.9.28. LOWLIGHT

LOWLIGHT Attribute Syntax
=======================================================================

 LOWLIGHT
 ~~~~~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

The "LOWLIGHT" clause controls the intensity of text ("FOREGROUND-COLOR") by setting that intensity to its lowest of three possible settings.

  1. This clause, along with "HIGHLIGHT" (see HIGHLIGHT), are intended to provide a three-level intensity scheme ("LOWLIGHT" … nothing (Normal) … "HIGHLIGHT"). In environments such as a Windows console where only two levels of intensity are supported, "LOWLIGHT" is the same as leaving this clause off altogether.

See Color Palette and Video Attributes, for more information on screen colors and video attributes.



5.9.29. NEXT GROUP

NEXT-GROUP Clause Syntax
=======================================================================

 NEXT GROUP IS { [ +|PLUS ] integer-2  }
 ~~~~ ~~~~~    {     ~~~~              }
               { NEXT|{NEXT PAGE}|PAGE }
                 ~~~~  ~~~~ ~~~~  ~~~~


=======================================================================
This syntax is valid in the following sections:
REPORT

This clause defines any rules for where the next group to be presented on a report will begin, line-wise, with respect to the last line of the group in which this clause appears.

  1. The reserved word "IS" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. The terms "NEXT"
  3. A report group must contain at least one "LINE NUMBER" clause in order to also contain a "NEXT GROUP" clause.
  4. If the "RD" (see REPORT SECTION) in which the report group containing a "NEXT GROUP" clause does not contain a "PAGE LIMITS" clause, only the "PLUS integer-1" option may be specified.
  5. The "NEXT PAGE" option cannot be used in a "PAGE FOOTING".
  6. The "NEXT GROUP" option cannot be specified in either a "REPORT HEADING" or a "PAGE HEADING".
  7. The effects of "NEXT GROUP" will be in addition to any line spacing defined by the next-presented group’s "LINE NUMBER" clause.


5.9.30. NO-ECHO

NO-ECHO Attribute Syntax
=======================================================================

 NO-ECHO
 ~~~~~~~


=======================================================================
This syntax is valid in the following sections:
SCREEN

The "NO-ECHO" clause will cause all data entered into the field to appear on the screen as asterisks.

  1. The "NO-ECHO" and "SECURE" (see SECURE) clauses are interchangeable, and may not be used together in the same data item description.
  2. This clause may only be used on a field allowing data entry (a field containing either the "USING" (see USING) or "TO" (see TO) clause).

See Color Palette and Video Attributes, for more information on screen colors and video attributes.



5.9.31. OCCURS

OCCURS (REPORT SECTION) Clause Syntax
=======================================================================

 OCCURS [ integer-1 TO ] integer-2 TIMES
 ~~~~~~             ~~
   [ DEPENDING ON identifier-1 ]
     ~~~~~~~~~
   [ STEP integer-3 ]
     ~~~~
   [ VARYING identifier-2 FROM { identifier-3 } BY { identifier-4 } ]
     ~~~~~~~              ~~~~ { integer-4    } ~~ { integer-5    }

=======================================================================
OCCURS (SCREEN SECTION) Clause Syntax
=======================================================================

 OCCURS integer-2 TIMES
 ~~~~~~

=======================================================================
OCCURS (All Other Sections Clause Syntax
=======================================================================

 OCCURS [ integer-1 TO ] integer-2 TIMES
 ~~~~~~             ~~
      [ DEPENDING ON identifier-1 ]
        ~~~~~~~~~
      [ ASCENDING|DESCENDING KEY IS identifier-5... ]...
        ~~~~~~~~~ ~~~~~~~~~~
      [ INDEXED BY identifier-6 ]
        ~~~~~~~

=======================================================================
This syntax is valid in the following sections:
FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT, SCREEN

The "OCCURS" clause is used to create a data structure called a table, where entries in that structure repeat multiple times.

  1. The reserved words "BY" (INDEXED), "IS", "KEY", "ON" and "TIMES" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The value of <integer-2> specifies how many entries will be allocated in the table.
  3. The following is an example of how a table might be defined:
    05 QUARTERLY-REVENUE OCCURS 4 TIMES PIC 9(7)V99.
    

    This will allocate the following:

    QUARTERLY-REVENUE(1)
    QUARTERLY-REVENUE(2)
    QUARTERLY-REVENUE(3)
    QUARTERLY-REVENUE(4)
    

    Each occurrence is referenced using the subscript syntax (a numeric literal, arithmetic expression or numeric identifier enclosed within parenthesis) shown above.

  4. The "OCCURS" clause may be used at the group level too, in which case the entire group structure repeats, as follows:
    05 GRP OCCURS 3 TIMES.
        10 A     PIC X(1).
        10 B     PIC X(1).
        10 C     PIC X(1).
    

    This would allow references to any of the following:

    GRP(1) - includes A(1), B(1) and C(1)
    GRP(2) - includes A(2), B(2) and C(2)
    GRP(3) - includes A(3), B(3) and C(3)
    

    or each A,B,C item could be referenced as follows:

    A(1) - Character #1 of GRP(1)
    B(1) - Character #2 of GRP(1)
    C(1) - Character #3 of GRP(1)
    A(2) - Character #1 of GRP(2)
    B(2) - Character #2 of GRP(2)
    C(2) - Character #3 of GRP(2)
    A(3) - Character #1 of GRP(3)
    B(3) - Character #2 of GRP(3)
    C(3) - Character #3 of GRP(3)
    
  5. The optional "DEPENDING ON"
  6. See the documentation of the "SEARCH" (see SEARCH), "SEARCH ALL" (see SEARCH ALL) and "SORT" (see SORT) statements for explanations of the "KEY"
  7. The "OCCURS" clause cannot be specified in a data description entry that has a level number of 01, 66, 77, or 88, although it is valid in data items described subordinate to an 01-level data item.
  8. The following points apply to an "OCCURS" used in the report section:
    1. The optional "STEP"
    2. The optional "VARYING"
    3. The following two examples illustrate two different ways a report could include four quarters worth of sales figures in it’s detail lines — one doing things ’the hard way’ and one using the advanced "OCCURS" capabilities of "STEP" and "VARYING". Both assume the definition of the following table exists in working-storage:
      05 SALES OCCURS 4 TIMES PIC 9(7)V99.

      First, the "Hard Way":

      10 COL 7  PIC $(7)9.99 SOURCE SALES(1).
      10 COL 17 PIC $(7)9.99 SOURCE SALES(2).
      10 COL 27 PIC $(7)9.99 SOURCE SALES(3).
      10 COL 37 PIC $(7)9.99 SOURCE SALES(4).
      

      And then using "STEP" and "VARYING":

      10 COL 7  OCCURS 4 TIMES STEP 10 VARYING QTR FROM 1 BY 1
                PIC $(7)9.99 SOURCE SALES(QTR).
      


5.9.32. OVERLINE

OVERLINE Attribute Syntax
=======================================================================

 OVERLINE
 ~~~~~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

The "OVERLINE" clause will introduce a horizontal line at the top edge of a screen field.

  1. The "LEFTLINE" (see LEFTLINE), "OVERLINE" and "UNDERLINE" (see UNDERLINE) clauses may be used in any combination in a single field’s description.
  2. This clause is essentially non-functional when used within Windows command shell (cmd.exe) environments and running programs compiled using a GnuCOBOL implementation built using ’PDCurses’ (such as Windows/MinGW builds).
  3. Whether or not this clause operates on Cygwin or UNIX/Linux/OSX systems will depend upon the video attribute capabilities of the terminal output drivers and ’curses’ software being used.

See Color Palette and Video Attributes, for more information on screen colors and video attributes.



5.9.33. PICTURE

PICTURE Clause Syntax
=======================================================================

 PICTURE IS picture-string
 ~~~

=======================================================================
This syntax is valid in the following sections:
FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT, SCREEN

The picture clause defines the class (numeric, alphabetic or alphanumeric), size and format of the data that may be contained by the data item being defined. Sometimes this role is assisted by the "USAGE" (see USAGE) clause, and in a few instances will be assumed entirely by that clause.

  1. The reserved word "IS" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. The reserved word "PICTURE" may be abbreviated as "PIC". Most programmers prefer to use the latter.
  3. A picture clause may only be specified on an elementary item.
  4. A <picture-string> is a sequence of the special symbols "$", "*", "+", ",", "-", ".", "/", "0" (zero), "9", "A", "B", "CR", "DB", "S", "V", "X" and "Z".
  5. In general, each picture symbol represents either a single character in storage or a single decimal digit. There are a few exceptions, and they will be discussed as needed.
  6. When a <picture-string> contains a repeated sequence of symbols — "PIC 9999/99/99" — for example, the repetition can be specified using a parenthetic repeat count, as in "PIC 9(4)/9(2)/9(2)". Using repeat counts is optional and their use (or not) is entirely at the discretion of the programmer. Many programmers use repetition for small sequences ("PIC XXX") and repeat counts for larger ones ("PIC 9(9)".
  7. This first set of picture symbols defines the basic data type of a data item. Each symbol represents a single character’s worth of storage.
    "A"

    Defines storage reserved for a single alphabetic character ("A"-"Z", "a"-"z").

    "N"

    Defines storage reserved for a single character in the computer’s ’National Character set

    "X"

    Defines storage reserved for a single alphanumeric character (any character).

    "9"

    Defines storage reserved for a single numeric digit character ("0"-"9").


    Typically, only one kind of each of those symbols is used in the same picture clause, but that isn’t a requirement. Data items that, of the three symbols above, use nothing but "A" picture symbols are known as ’Alphabetic Data Items

    If you need to allocate space for a data item whose format is two letters followed by five digits followed by three letters, you could use the <picture-string> "AA99999AAA", "A(2)9(5)A(3)" "XXXXXXXXXX" or "X(10)". There is absolutely no functional difference whatsoever between the four — none of them provide any functionality the others do not. The first two probably make for better documentation of the expected field contents, but they don’t provide any run-time enforcement capabilities.

    As far as enforcement goes, however, both alphabetic and numeric picture strings do provide for both compile-time and run-time enforcement capabilities. In the case of compilation enforcement, the compiler can issue warning messages if you attempt to specify a non-numeric value for a numeric data item or if you attempt to "MOVE" (see MOVE) a non-numeric data item to one that is numeric. Similar capabilities exist for alphabetic data items. At run-time, you may use a special class test (see Class Conditions) to determine if the contents of a data item are entirely numeric or entirely alphabetic.

  8. The following picture symbols may be used with numeric data items.
    "P"

    Defines an implied digit position that will be considered to be a zero when the data item is referenced at run-time. This symbol is used to allow data items that will contain very large values to be allocated using less storage by assuming a certain number of trailing zeros (one per "P") to exist at the end of values.

    The "P" symbol is not allowed in conjunction with "N".

    The "P" symbol may only be used at the beginning or end of a picture clause.

    "P" is a repeatable symbol.

    All computations and "MOVE" (see MOVE) operations involving such a data item will behave as if the zeros were actually there.

    For example, let’s say you need to allocate a data item that contains however many millions of dollars of revenue your company has in gross revenues this year:

    01 Gross-Revenue PIC 9(9).

    In which case 9 characters of storage will be reserved. The values 000000000 through 999999999 will represent the gross-revenues. But, if only the millions are tracked (meaning the last six digits are always going to be 0), you could define the field as:

    01 Gross-Revenue PIC 9(3)P(6).

    Whenever Gross-Revenue is referenced in calculations, or whenever its value is moved to another data item, the value of Gross-Revenue will be treated as if it is nnn000000, where ’nnn’ is the actual value in storage.

    If you wanted to store the value 128 million into that field, you would do so as if the "P"s were "9"s:

    MOVE 128000000 TO Gross-Revenue

    A "DISPLAY" (see DISPLAY) of a data item containing "P" symbols is a little strange. The value displayed will be what is actually in storage, but the total size of the displayed value will be as if the "P" symbols had been "9"s. Thus, after the above statement established a value for Gross-Revenue, a "DISPLAY Gross-Revenue" would produce output of ’000000128’.

    "S"

    This symbol, if used, must be the very first symbol in the "PICTURE" value. A "S" indicates that the data item is "Signed", meaning that negative values are possible for this data item. Without an "S", any negative values stored into this data item via a "MOVE" or arithmetic statement will have the negative sign stripped from it (in effect becoming the absolute value).

    The "S" symbol is not allowed in conjunction with "N".

    The "S" symbol may only occur once in a picture string. See SIGN IS, for further discussion of how negative values may be stored in a numeric data item.

    "V"

    This symbol is used to define where an implied decimal-point (if any) is located in a numeric item. Just as there may only be a single decimal point in a number so may there be no more than one "V" in a "PICTURE". Implied decimal points occupy no space in storage — they just specify how values are used. For example, if the value "1234" is in storage in a field defined as PIC 999V9, that value would be treated as 123.4 in any statements that referenced it.

    The "V" symbol is not allowed in conjunction with "N".

    The "V" symbol may only occur once in a picture string.

  9. Any editing symbols introduced past this point will, if coded in the picture clause of an otherwise numeric data item, transform that data item from a numeric to a ’Numeric Edited
  10. The following are the fixed insertion editing symbols that may be specified in a picture string. Each of these editing symbols will insert a special character into the field value at the position it is specified in the picture string. These editing symbols will each introduce one extra character into the total field size for each occurrence of the symbol in the picture string.
    "B"

    The "B" editing symbol introduces a blank into the field value for each occurrence.

    Multiple "B" symbols may be coded.

    The following example will format a ten digit number (presumably a telephone number) into a "### ### ####" layout:

        ...
            05 Phone-Number       PIC 9(3)B9(3)B9(4).
        ...
            MOVE 5185551212 TO Phone-Number
            DISPLAY Phone-Number
    

    This code will display "518 555 1212".

    "0"

    The "0" (zero) editing symbol introduces one "0" character into the field value for each occurrence in the picture string.

    Multiple "0" symbols may be coded.

    Here’s an example:

        ...
            05  Output-Item     PIC 909090909.
        ...
            MOVE 12345 TO Output-Item
            DISPLAY Output-Item
    

    The above will display "102030405".

    "/"

    The "/" editing symbol inserts one "/" character into the field value for each occurrence in the picture string.

    Multiple "/" symbols may be coded.

    This editing symbol is most-frequently used to format dates, as follows:

        ...
            05  Year-Month-Day   PIC 9(4)/9(2)/9(2).
        ...
            MOVE 20140207 TO Year-Month-Day
            DISPLAY Year-Month-Day
    

    This example displays "2014/02/07".

  11. The following are the numeric formatting symbols that may be specified in a picture string. Each of these editing symbols will insert special characters into the field value to present numbers in a "friendly" format. These editing symbols will each introduce one extra character into the total field size for each occurrence of the symbol in the picture string. Numeric fields whose picture clause contains these characters may neither be used as source fields in any calculation nor may they serve as source fields for the transfer of data values to any data item other than an alphanumeric field.
    "."

    The "." symbol inserts a decimal point into a numeric field value. When the contents of a numeric data item sending field are moved into a receiving data item whose picture clause contains the "." editing symbol, implied ("V") or actual decimal point in the sending data item or literal, respectively, will be aligned with the "." symbol in the receiving field. Digits are then transferred from the sending to the receiving field outward from the sending field’s "V" or ".", truncating sending digits if there aren’t enough positions in the receiving field. Any digit positions in the receiving field that don’t receive digits from the sending field, if any, will be set to 0.

    The "." symbol is not allowed in conjunction with "N".

    An example will probably help:

        ...
        05  Source-Field   PIC 9(2)V9 VALUE 7.2.
        05  Dest-Field     PIC 9(5).9(2).
        ...
        MOVE 1234567.89 TO Dest-Field
        DISPLAY Dest-Field
        MOVE 19 TO Dest-Field
        DISPLAY Dest-Field
        MOVE Source-Field TO Dest-Field
        DISPLAY Dest-Field
    

    The example will display three results — "34567.89", "00019.00" and "00007.20".

    Both data item definitions appear to have two decimal points in their picture clauses. They actually don’t, because the last character of every data item definition is always a period — the period that ends the definition.

    ","

    The "," symbol serves as a thousands separator. Many times, you’ll see large numbers formatted with these symbols — for example, 123,456,789. This can be accomplished easily by adding thousands separator symbols to a picture string. Thousands separator symbols that aren’t needed will behave as if they were "9"s.

    The "," symbol is not allowed in conjunction with "N".

    Here’s an example:

        ...
        05  My-Lottery-Winnings   PIC 9(3),9(3),9(3).
        ...
        MOVE 12345 TO My-Lottery-Winnings
        DISPLAY My-Lottery-Winnings
    

    The value "0000012,345" (a very disappointing one for my retirement plans, but a good thousands separator demo) will be displayed. Notice how, since the first comma wasn’t needed due to the meagre amount I won, it behaved like another "9".


    If desired, you may reverse the roles of the "." and "," editing symbols by specifying "DECIMAL POINT IS COMMA" in the "SPECIAL-NAMES" (see SPECIAL-NAMES) paragraph.

  12. The following are insertion symbols. They are used to insert an extra character (two in the case of "CR" and "DB") to signify the sign (positive or negative) of the numeric value that is moved into the field whose picture string contains one of these symbols, or the fact that the data item represents a currency (money) amount. Only one of the "+", "-", "CR" or "DB" symbols may be used in a picture clause. In this context, when any of these symbols are used in a <picture-string>, they must be at the end. The "+", "-" and/or currency symbols may also be used as floating editing symbols at the beginning of the <picture-string> — a subject that will be covered in the next numbered paragraph.
    "+"

    If the value of the numeric value moved into the field is positive (0 or greater), a "+" character will be inserted. If the value is negative (less than 0), a "-" character is inserted.

    The "+" symbol is not allowed in conjunction with "N".

    "-"

    If the value of the numeric value moved into the field is positive (0 or greater), a space will be inserted. If the value is negative (less than 0), a "-" character is inserted.

    The "-" symbol is not allowed in conjunction with "N".

    "CR"

    This symbol is coded as the two characters "C" and "R". If the value of the numeric value moved into the field is positive (0 or greater), two spaces will be inserted. If the value is negative (less than 0), the characters "CR" (credit) are inserted.

    The "CR" symbol is not allowed in conjunction with "N".

    "DB"

    This symbol is coded as the two characters "D" and "B". If the value of the numeric value moved into the field is positive (0 or greater), two spaces will be inserted. If the value is negative (less than 0), the characters "DB" (debit) are inserted.

    The "DB" symbol is not allowed in conjunction with "N".

    "$"

    Regardless of the value moved into the field, this symbol will insert the currency symbol into the data item’s value in the position where it occurs in the <picture-string> (see SPECIAL-NAMES).

    The "$" symbol is not allowed in conjunction with "N".

  13. These editing symbols are known as floating replacement symbols. These symbols may occur in sequences before any "9" editing symbols in the <picture-string> of a numeric data item. Using these symbols transforms that numeric data item into a numerid edited data item, which can no longer be used in calculations or subscripts.
  14. Each of the following symbols behave like a "9", until such point as all digits in the numeric value are exhausted and leading zeros are about to be inserted. In effect, these editing symbols define what should happen to those leading zero.
    "$"

    Of those currency symbols that correspond to character positions in which leading zeros reside, the right-most will have its "0" value replaced by the currency symbol in-effect for the program (see SPECIAL-NAMES). Any remaining leading zero values occupying positions described by this symbol will be replaced by spaces.

    The "$" symbol is not allowed in conjunction with "N".

    Any currency symbol coded to the right of a "." will be treated exactly like a "9".

    "*"

    This symbol is referred to as a check protection symbol. All check-protection symbols that correspond to character positions in which leading zeros reside will have their "0" values replaced by "*".

    The "*" symbol is not allowed in conjunction with "N".

    Any check-suppression symbol coded to the right of a "." will be treated exactly like a "9".

    "+"

    Of those "+" symbols that correspond to character positions in which leading zeros reside, the right-most will have its "0" value replaced by a "+" if the value in the data item is zero or greater or a "-" otherwise. Any remaining leading zero values occupying positions described by this symbol will be replaced by spaces. You cannot use both "+" and "-" in the same <picture-string>.

    The "+" symbol is not allowed in conjunction with "N".

    Any "+" symbol coded to the right of a "." will be treated exactly like a "9".

    "-"

    Of those "-" symbols that correspond to character positions in which leading zeros reside, the right-most will have its "0" value replaced by a space if the value in the data item is zero or greater or a "-" otherwise. Any remaining leading zero values occupying positions described by this symbol will be replaced by spaces. You cannot use both "+" and "-" in the same <picture-string>.

    The "-" symbol is not allowed in conjunction with "N".

    Any "-" symbol coded to the right of a "." will be treated exactly like a "9".

    "Z"

    All "Z" symbols that correspond to character positions in which leading zeros reside will have their "0" values replaced by spaces.

    Any zero-suppression symbol coded to the right of a "." will be treated exactly like a "9".

    "Z" and "*" should not be coded in the same <picture-string>

    "+" and "-" should not be coded in the same <picture-string>

    When multiple floating symbols are coded, even if there is only one of them used they will all be considered floating and will all be able to assume each other’s properties. For example, if a data item has a "PIC +$ZZZZ9.99" <picture-string>, and a value of 1 is moved to that field at run-time, the resulting value will be (the b symbol represents a space) "bbbb+$1.00". This is not consistent with many other COBOL implementations, where the result would have been "+$bbbb1.00".

    Most other COBOL implementations reject the use of multiple occurrences of multiple floating editing symbols. For example, they would reject <picture-string>s such as "+++$$$9.99", "$$$ZZZ9.99" and so on. GnuCOBOL accepts these. Programmers creating GnuCOBOL programs should avoid such <picture-string>s if there is any likelihood that those programs may be used with other COBOL implementations.



5.9.34. PRESENT WHEN

PRESENT-WHEN Clause Syntax
=======================================================================

 PRESENT WHEN condition-name
 ~~~~~~~ ~~~~

=======================================================================
This syntax is valid in the following sections:
REPORT

This clause names an existing "Condition Name" (see Condition Names) that will serve as a switch controlling the presentation or suppression of a report group.

  1. If the specified condition-name has a value of FALSE when a "GENERATE" statement (see GENERATE) causes a report group to be presented, the presentation of that group will be suppressed.
  2. If the condition-name has a value of TRUE, the group will be presented.
  3. See Condition Names, for more information.


5.9.35. PROMPT

PROMPT Clause Syntax
=======================================================================

 PROMPT [ CHARACTER IS literal-1 | identifier-1 ]
 ~~~~~~   ~~~~~~~~~


=======================================================================
This syntax is valid in the following sections:
SCREEN

This clause defines the character that will be used as the fill-character for any input fields on the screen.

  1. The reserved word "IS" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. The default prompt character, should no "CHARACTER" specification be coded, or should the "PROMPT" clause be absent altogether, is an underscore ("_").
  3. Prompt characters will be automatically transformed into spaces upon input.

See Color Palette and Video Attributes, for more information on screen colors and video attributes.



5.9.36. PROTECTED

PROTECTED Attribute Syntax
=======================================================================

 PROTECTED SIZE IS { identifier }
 ~~~~~~~~  ~~~~    { integer    }

=======================================================================
This syntax is valid in the following sections:
SCREEN
  1. The "PROTECTED" extended clause will effect the specified field to be limited in size, regardless of the picture size. OR DOES IT?
  2. The SIZE phrase specifies the size (length) of the field. After the ACCEPT or DISPLAY is finished, the cursor is placed immediately after the field defined by this clause, unless this would place the cursor outside of the current terminal window. In this case, the cursor is wrapped around to the beginning of the next line (scrolling the window if necessary).
  3. If the SIZE phrase is not used, then the field length defaults to the size of the item being accepted or displayed. If the CONVERT phrase is used, however, then the size of the field depends on the data type of the item and the verb being used.
    1. If the DISPLAY verb is executing, then the size is the same as if the CONVERT phrase were not specified except for numeric items. For numeric items, the size is the number of digits in the item, plus one if it is not an integer, plus one if it is signed. The remaining cases cover the size when an ACCEPT statement is used.
    2. If the item is numeric or numeric edited, then the size is the number of digits in the item, plus one if it is not an integer, plus one if it is signed.
    3. If the item is alphanumeric edited, then the size is set to the number of "A" or "X" positions specified in its PICTURE clause.
    4. For all other data types, the field size is set to the size of the item (same as if CONVERT were not specified).
  4. Note that the OUTPUT phrase changes the way in which the default field size is computed. See that heading above for details. Also note that the OUTPUT phrase affects only the way items are displayed on the screen; the internal format of accepted data is not affected.
  5. Note that you cannot supply the CONVERT phrase in the Screen Section. Thus the size of a Screen Section field is always the size of its screen entry unless the SIZE phrase is specified.


5.9.37. REDEFINES

REDEFINES Clause Syntax
=======================================================================

 REDEFINES identifier-1
 ~~~~~~~~~

=======================================================================
This syntax is valid in the following sections:
FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE

The "REDEFINES" clause causes the data item in who’s definition the "REDEFINES" clause is specified (hereafter referred to as the redefines object) to occupy the same physical storage space as <identifier-1> (hereafter referred to as the redefines subject).

  1. The following rules must all be followed in order to use REDEFINES:
    1. The level number of both the subject and object data items must be the same.
    2. The level numbers of both the subject and object data items cannot be 66, 78 or 88.
    3. If "n" represents the level number of the object, then no other data items with level number "n" may be defined between the subject and object data items unless they too are "REDEFINES" of the subject.
    4. If "n" represents the level number of the object, then no other data items with a level number numerically less than "n" may be defined between the subject and object data items.
    5. The total allocated size of the subject data item must be the same as the total allocated size of the object data item.
    6. No "OCCURS" (see OCCURS) clause may be part of the definition of either the subject or object data items. Either or both, however, may be group items that contain data items with "OCCURS" clauses.
    7. No "VALUE" (see VALUE) clause may be defined on the object data item, and no data items subordinate to the object data item may have "VALUE" clauses, with the exception of level-88 condition names.


5.9.38. RENAMES

RENAMES Clause Syntax
=======================================================================

 RENAMES identifier-1 [ THRU|THROUGH identifier-2
 ~~~~~~~                ~~~~ ~~~~~~~

=======================================================================
This syntax is valid in the following sections:
FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE

The "RENAMES" clause regroups previously defined items by specifying alternative, possibly overlapping, groupings of elementary data items.

  1. The reserved words "THRU" and "THROUGH" are interchangeable.
  2. You must use the level number 66 for data description entries that contain the "RENAMES" clause.
  3. The <identifier-1> and <identifier-2> data items, along with all data items defined between those two data items in the program source, must all be contained within the same 01-level record description.
  4. See 66-Level Data Items, for additional information on the RENAMES clause.


5.9.39. REQUIRED

REQUIRED Attribute Syntax
=======================================================================

 REQUIRED
 ~~~~~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

This clause forces the user to enter data into the field it is specified on (or into all subordinate input-capable fields if "REQUIRED" is specified on a group item).

  1. The "EMPTY-CHECK" (see EMPTY-CHECK) and "REQUIRED" clauses are interchangeable, and may not be used together in the same data item description.
  2. In order to take effect, the user must first move the cursor into the field having this clause in its definition.
  3. The "ACCEPT screen-data-item" statement (see ACCEPT screen-data-item) will ignore the Enter key and any other cursor-moving keystrokes that would cause the cursor to move to another screen item unless data has been entered into the field. Function keys will still be allowed to terminate the "ACCEPT".
  4. In order to be functional, this attribute must be supported by the underlying ’curses’ package your GnuCOBOL implementation was built with. As of this time, the ’PDCurses’ package (used for native Windows or MinGW builds) does not support "REQUIRED".


5.9.40. REVERSE-VIDEO

REVERSE-VIDEO Attribute Syntax
=======================================================================

 REVERSE-VIDEO
 ~~~~~~~~~~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

The "REVERSE-VIDEO" attribute swaps the specified or implied "FOREGROUND-COLOR" (see FOREGROUND-COLOR) and "BACKGROUND-COLOR" (see BACKGROUND-COLOR) attributes for the field whose definition contains this clause (or all subordinate fields if used on a group item).

See Color Palette and Video Attributes, for more information on screen colors and video attributes.



5.9.41. SECURE

SECURE Attribute Syntax
=======================================================================

 SECURE
 ~~~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

This clause will cause all data entered into the field to appear on the screen as asterisks.

  1. The "NO-ECHO" (see NO-ECHO) and "SECURE" clauses are interchangeable, and may not be used together in the same data item description.
  2. This clause may only be used on a field allowing data entry (a field containing either the "USING" (see USING) or "TO" (see TO) clause).

See Color Palette and Video Attributes, for more information on screen colors and video attributes.



5.9.42. SIGN IS

SIGN-IS Clause Syntax
=======================================================================

 SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ]
 ~~~~    ~~~~~~~ ~~~~~~~~   ~~~~~~~~

=======================================================================
This syntax is valid in the following sections:
FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT, SCREEN

This clause, allowable only for "USAGE DISPLAY" numeric data items, specifies how an "S" symbol will be interpreted in a data item’s picture clause.

  1. The reserved words "CHARACTER" and "IS" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. Without the "SEPARATE CHARACTER"
    First/Last DigitValue For PositiveValue for Negative
    00p
    11q
    22r
    33s
    44t
    55u
    66v
    77w
    88x
    99y
  3. If the "SEPARATE CHARACTER" clause is used, then an actual "+" or "-" character will be inserted into the field’s value as the first ("LEADING") or last ("TRAILING") character. Note that having this character embedded within the data item’s storage does not prevent the data item from being used as a source field in arithmetic operations.
  4. When "SEPARATE CHARACTER" is specified, the "S" symbol in the data item’s "PICTURE" must be counted when determining the data item’s size.
  5. Neither the presence of an encoded digit (see above) nor an actual "+" or "-" character embedded within the data item’s storage prevents the data item from being used as a source field in arithmetic operations.


5.9.43. SOURCE

SOURCE Clause Syntax
=======================================================================

 SOURCE IS literal-1 | identifier-1 [ ROUNDED ]
 ~~~~~~                               ~~~~~~~

=======================================================================
This syntax is valid in the following sections:
REPORT

This clause logically attaches a report section data item to another data item defined elsewhere in the data division.

  1. The reserved word "IS" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. When the report group containing this clause is presented, the value of the specified numeric literal or identifier will be automatically moved to the report data item prior to presentation.
  3. The specified identifier may be defined anywhere in the data division, but if it is defined in the report section it may only be "PAGE-COUNTER"
  4. The "PICTURE" (see PICTURE) of the report data item must be such that it would be legal to "MOVE" (see MOVE) the specified literal or identifier to a data item with that "PICTURE".
  5. The "ROUNDED" option comes into play should the number of digits to the right of an actual or assumed decimal point be different between the specified literal or identifier value (the "source value") and the "PICTURE" specified for the field in whose definition the "SOURCE" clause appears (the "target field"). Without "ROUNDED", excess digits in the source value will simply be truncated to fit the target field. With "ROUNDED", the source value will be arithmetically rounded to fit the target field. See ROUNDED, for information on the "NEAREST-AWAY-FROM-ZERO" rounding rule, which is the one that will apply.


5.9.44. SUM OF

SUM-OF Clause Syntax
=======================================================================

 SUM OF { identifier-7 }... [ { RESET ON FINAL|identifier-8 } ]
 ~~~    { literal-2    }      { ~~~~~    ~~~~~              }
                              { UPON identifier-9           }
                                ~~~~

=======================================================================
This syntax is valid in the following sections:
REPORT

The "SUM" clause establishes a summation counter whose value will be arithmetically calculated whenever the field is presented.

  1. The reserved words "OF" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The "SUM" clause may only appear in a "CONTROL FOOTING" report group.
  3. If the data item in which the "SUM" clause appears has been assigned it’s own identifier name, and that name is not "FILLER", then that data item is referred to as a sum counter.
  4. All <identifier-7> data items must be non-edited numeric in nature.
  5. If any <identifier-7> data item is defined in the report section, it must be a sum counter.
  6. Any <identifier-7> data items that are sum counters must either be defined in the same report group as the data item in which this "SUM" clause appears or they must be defined in a report data item that exists at a lower level in this report’s control hierarchy. See Control Hierarchy, for additional information.
  7. The "PICTURE" of the report data item in who’s description this "SUM" clause appears in must be such that it would be legal to "MOVE" (see MOVE) the specified <identifier-7> or <literal-2> value to a data item with that "PICTURE".
  8. The following points apply to the "UPON"
    1. The data item <identifier-9> must be the name of a detail group specified in the same report as the control footing group in which this "SUM" clause appears.
    2. The presence of an "UPON" clause limits the "SUM" clause to adding the specified numeric literal or identifier value into the sum counter only when a "GENERATE <identifier-9>" statement is executed.
    3. If there is no "UPON" clause specified, the value of <identifier-7> or <literal-2> will be added into the sum counter whenever a "GENERATE" (see GENERATE) of any detail report group in the report is executed.
    4. If there is only a single detail group in the report’s definition, the "UPON" clause is meaningless.
  9. The following points apply to the "RESET"
    1. If the "RESET" option is coded, "FINAL" or <identifier-8> (whichever is coded on the "RESET") must be one of the report’s control breaks specified on the "CONTROLS" clause.
    2. If there is no "RESET" option coded, the sum counter will be reset back to zero after each time the control footing containing the "SUM" clause is presented. This is the typical behaviour that would be expected.
    3. If, however, you want to reset the "SUM" counter only when the control footing for a control break higher in the control hierarchy is presented, specify that higher control break on the "RESET" option.


5.9.45. SYNCRONIZED

SYNCRONIZED Syntax
=======================================================================

 SYNCRONIZED|SYNCHRONISED [ LEFT|RIGHT ]
 ~~~~        ~~~~           ~~~~ ~~~~~

The "LEFT" and "RIGHT" (SYNCRONIZED) clauses are syntactically recognized but are otherwise non-functional.


=======================================================================
This syntax is valid in the following sections:
FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE

This optional clause optimizes the storage of binary numeric items to store them in such a manner as to make it as fast as possible for the CPU to fetch them.

  1. The reserved words "SYNCRONIZED" and "SYNCHRONISED" are interchangeable, and may be abbreviated as "SYNC".
  2. If the "SYNCRONIZED" clause is coded on anything but a numeric data item with a "USAGE" (see USAGE) that specifies storage of data in a binary form, the "SYNCRONIZED" clause will be ignored.
  3. Synchronization is performed (by the compiler) as follows:
    1. If the binary item occupies one byte of storage, no synchronization is performed.
    2. If the binary item occupies two bytes of storage, the binary item is allocated at the next half-word boundary.
    3. If the binary item occupies four bytes of storage, the binary item is allocated at the next word boundary.
    4. If the binary item occupies four bytes of storage, the binary item is allocated at the next word boundary.


5.9.46. TO

TO Clause Syntax
=======================================================================

 TO identifier-5
 ~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

This clause logically attaches a screen section data item to another data item defined elsewhere in the data division.

  1. The "TO" clause is used to define a data-entry field with no initial value; when a value is entered, it will be saved to the specified identifier.
  2. The "FROM" (see FROM), "TO", "USING" (see USING) and "VALUE" (see VALUE) clauses are mutually-exclusive in any screen section data item’s definition.


5.9.47. TYPE

TYPE Clause Syntax
=======================================================================

 [ TYPE IS { RH|{REPORT HEADING}                      } ]
   ~~~~    { ~~  ~~~~~~ ~~~~~~~                       }
           { PH|{PAGE HEADING}                        }
           { ~~  ~~~~ ~~~~~~~                         }
           { CH|{CONTROL HEADING} FINAL|identifier-2  }
           { ~~  ~~~~~~~ ~~~~~~~  ~~~~~               }
           { DE|DETAIL                                }
           { ~~ ~~~~~~                                }
           { CF|{CONTROL FOOTING} FINAL|identifier-2  }
           { ~~  ~~~~~~~ ~~~~~~~  ~~~~~               }
           { PF|{PAGE FOOTING}                        }
           {  ~~ ~~~~ ~~~~~~~                         }
           { RF|{REPORT FOOTING}                      }
             ~~  ~~~~~~ ~~~~~~~

=======================================================================
This syntax is valid in the following sections:
REPORT

This clause defines the type of report group that is being defined for a report.

  1. This clause is required on any 01-level data item definitions (other than 01-level constants) in the report section. This clause is invalid on any other report section data item definitions.
  2. There may be a maximum of one (1) report group per "RD" defined with a "TYPE" of "REPORT HEADING", "PAGE HEADING", "PAGE FOOTING" and "REPORT FOOTING".
  3. There must be either a "CONTROL HEADING" or a "CONTROL FOOTING" or both specified for each entry specified on the "CONTROLS ARE" clause of the "RD".
  4. The various report groups that constitute a report may be defined in any order.
  5. See RWCS Lexicon, for a description of the seven different types of report groups.


5.9.48. UNDERLINE

UNDERLINE Attribute Syntax
=======================================================================

 UNDERLINE
 ~~~~~~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

The "UNDERLINE" clause will introduce a horizontal line at the bottom edge of a screen field.

  1. The "LEFTLINE" (see LEFTLINE), "OVERLINE" (see OVERLINE) and "UNDERLINE" clauses may be used in any combination in a single field’s description.
  2. This clause is essentially non-functional when used within Windows command shell (cmd.exe) environments and running programs compiled using a GnuCOBOL implementation built using ’PDCurses’ (such as Windows/MinGW builds).
  3. Whether or not this clause operates on Cygwin or UNIX/Linux/OSX systems will depend upon the video attribute capabilities of the terminal output drivers and ’curses’ software being used.

See Color Palette and Video Attributes, for more information on screen colors and video attributes.



5.9.49. USAGE

USAGE Clause Syntax
=======================================================================

 USAGE IS data-item-usage
 ~~~~~

=======================================================================
This syntax is valid in the following sections:
FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT

The "USAGE" clause defines the format that will be used to store the value of a data item.

  1. The reserved word "IS" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. The following table summarizes the various USAGE specifications available in GnuCOBOL.

    BINARY
    ~~~~~~

    Range of Values:Defined by the quantity of "9"s and the presence or absence of an "S" in the "PICTURE"
    Storage Format:Compatible Binary Integer
    Negative Values Allowed?:If "PICTURE" contains "S"
    "PICTURE" Used?:Yes

    BINARY-C-LONG [ SIGNED ]
    ~~~~~~~~~~~~~

    Same as "BINARY-DOUBLE SIGNED"

    BINARY-C-LONG UNSIGNED
    ~~~~~~~~~~~~~ ~~~~~~~~

    Range of Values:Typically 0 to 4,294,967,295
    Storage Format:Native Binary Integer
    Negative Values Allowed?:No
    "PICTURE" Used?:No

    BINARY-CHAR [ SIGNED ]
    ~~~~~~~~~~~

    Range of Values:-128 to 127
    Storage Format:Native Binary Integer
    Negative Values Allowed?:Yes
    "PICTURE" Used?:No

    BINARY-CHAR UNSIGNED
    ~~~~~~~~~~~ ~~~~~~~~

    Range of Values:0 to 255
    Storage Format:Native Binary Integer
    Negative Values Allowed?:No
    "PICTURE" Used?:No

    BINARY-DOUBLE [ SIGNED ]
    ~~~~~~~~~~~~~

    Range of Values:-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
    Storage Format:Native Binary Integer
    Negative Values Allowed?:Yes
    "PICTURE" Used?:No

    BINARY-DOUBLE UNSIGNED
    ~~~~~~~~~~~~~ ~~~~~~~~

    Range of Values:0 to 18,446,744,073,709,551,615
    Storage Format:Native Binary Integer
    Negative Values Allowed?:No
    "PICTURE" Used?:No

    BINARY-INT
    ~~~~~~~~~~

    Same as "BINARY-LONG SIGNED"

    BINARY-LONG [ SIGNED ]
    ~~~~~~~~~~~

    Range of Values:-2,147,483,648 – 2,147,483,647
    Storage Format:Native Binary Integer
    Negative Values Allowed?:Yes
    "PICTURE" Used?:No

    BINARY-LONG UNSIGNED
    ~~~~~~~~~~~ ~~~~~~~~

    Range of Values:0 to 4,294,967,295
    Storage Format:Native Binary Integer
    Negative Values Allowed?:No
    "PICTURE" Used?:No

    BINARY-LONG-LONG
    ~~~~~~~~~~~~~~~~

    Same as "BINARY-DOUBLE SIGNED"

    BINARY-SHORT [ SIGNED ]
    ~~~~~~~~~~~~

    Range of Values:-32,768 to 32,767
    Storage Format:Native Binary Integer
    Negative Values Allowed?:Yes
    "PICTURE" Used?:No

    BINARY-SHORT UNSIGNED
    ~~~~~~~~~~~~ ~~~~~~~~

    Range of Values:0 to 65,535
    Storage Format:Native Binary Integer
    Negative Values Allowed?:No
    "PICTURE" Used?:No

    COMPUTATIONAL
    ~~~~

    Same as "BINARY"

    COMP[UTATIONAL]-1
    ~~~~ ~~

    Same as "FLOAT-SHORT"

    COMP[UTATIONAL]-2
    ~~~~ ~~

    Same as "FLOAT-LONG"

    COMP[UTATIONAL]-3
    ~~~~ ~~

    Same as "PACKED-DECIMAL"

    COMP[UTATIONAL]-4
    ~~~~ ~~

    Same as "BINARY"

    COMP[UTATIONAL]-5
    ~~~~ ~~

    Range of Values:Depends on number of "9"s in the "PICTURE" and the "binary-size" setting of the configuration file used to compile the program
    Storage Format:Native Binary Integer
    Negative Values Allowed?:If "PICTURE" contains "S"
    "PICTURE" Used?:Yes

    COMP[UTATIONAL]-6
    ~~~~ ~~

    Range of Values:Defined by the quantity of "9"s and the presence or absence of an "S" in the "PICTURE"
    Storage Format:Unsigned Packed Decimal
    Negative Values Allowed?:No
    "PICTURE" Used?:Yes

    COMP[UTATIONAL]-X
    ~~~~ ~~

    Range of Values:If used with "PIC X", allocates one byte of storage per "X"; range of values is 0 to max storable in that many bytes. If used with "PIC 9", range of values depends on number of "9"s in PICTURE
    Storage Format:Native unsigned (X) or signed (9) Binary
    Negative Values Allowed?:If "PICTURE" 9 and contains "S"
    "PICTURE" Used?:Yes

    DISPLAY
    ~~~~~~~

    Range of Values:Depends on "PICTURE" – One character per X, A, 9, period, $, Z, 0, *, S (if "SEPARATE CHARACTER" specified), +, - or B symbol in "PICTURE"; Add 2 more bytes if the "DB" or "CR" editing symbol is used
    Storage Format:Characters
    Negative Values Allowed?:If "PICTURE" contains "S"
    "PICTURE" Used?:Yes

    FLOAT-DECIMAL-16
    ~~~~~~~~~~~~~~~~

    Range of Values:9.999999999999999×10^384 to 9.999999999999999×10^384
    Storage Format:Native IEEE 754 Decimal64 Floating-point
    Negative Values Allowed?:Yes
    "PICTURE" Used?:No

    FLOAT-DECIMAL-34
    ~~~~~~~~~~~~~~~~

    Range of Values:-9.99999...×10^6144 to 9.99999...×10^6144
    Storage Format:Native IEEE 754 Decimal128 Floating-point
    Negative Values Allowed?:Yes
    "PICTURE" Used?:No

    FLOAT-LONG
    ~~~~~~~~~~

    Range of Values:Approximately -1.797693134862316×10^308 to 1.797693134862316×10^308
    Storage Format:Native IEEE 754 Binary64 Floating-point
    Negative Values Allowed?:Yes
    "PICTURE" Used?:No

    FLOAT-SHORT
    ~~~~~~~~~~~

    Range of Values:Approximately -3.4028235×10^38 to 3.4028235×10^38
    Storage Format:Native IEEE 754 Binary32
    Negative Values Allowed?:Yes
    "PICTURE" Used?:No

    INDEX
    ~~~~~

    Range of Values:0 to maximum address possible (32 or 64 bits)
    Storage Format:Native Binary Integer
    Negative Values Allowed?:No
    "PICTURE" Used?:No

    NATIONAL
    ~~~~~~~~

    "USAGE NATIONAL", while syntactically recognized, is not supported by GnuCOBOL

    PACKED-DECIMAL
    ~~~~~~~~~~~~~~

    Range of Values:Defined by the quantity of "9"s and the presence or absence of an "S" in the PICTURE
    Storage Format:Signed Packed Decimal
    Negative Values Allowed?:If "PICTURE" contains "S"
    "PICTURE" Used?:No

    POINTER
    ~~~~~~~

    Range of Values:0 to maximum address possible (32 or 64 bits)
    Storage Format:Native Binary Integer
    Negative Values Allowed?:No
    "PICTURE" Used?:No

    PROCEDURE-POINTER
    ~~~~~~~~~~~~~~~~~

    Same as "PROGRAM-POINTER"

    PROGRAM-POINTER
    ~~~~~~~~~~~~~~~

    Range of Values:0 to maximum address possible (32 or 64 bits)
    Storage Format:Native Binary Integer
    Negative Values Allowed?:No
    "PICTURE" Used?:No

    SIGNED-INT
    ~~~~~~~~~~

    Same as "BINARY-LONG SIGNED"

    SIGNED-LONG
    ~~~~~~~~~~~

    Same as "BINARY-DOUBLE SIGNED"

    SIGNED-SHORT
    ~~~~~~~~~~~~

    Same as "BINARY-SHORT SIGNED"

    UNSIGNED-INT
    ~~~~~~~~~~~~

    Same as "BINARY-LONG UNSIGNED"

    UNSIGNED-LONG
    ~~~~~~~~~~~~~

    Same as "BINARY-DOUBLE UNSIGNED"

    UNSIGNED-SHORT
    ~~~~~~~~~~~~~~

    Same as "BINARY-SHORT UNSIGNED"
  3. Binary data (integer or floating-point) can be stored in either a Big-Endian or Little-Endian form.

    Big-endian data allocation calls for the bytes that comprise a binary item to be allocated such that the least-significant byte is the right-most byte. For example, a four-byte binary item having a value of decimal 20 would be big-endian allocated as 00000014 (shown in hexadecimal notation).

    Little-endian data allocation calls for the bytes that comprise a binary item to be allocated such that the least-significant byte is the left-most byte. For example, a four-byte binary item having a value of decimal 20 would be little-endian allocated as 14000000 (shown in hexadecimal notation).

    All CPUs are capable of "understanding" big-endian format, which makes it the "most-compatible" form of binary storage across computer systems.

    Some CPUs – such as the Intel/AMD i386/x64 architecture processors used in most Windows PCs – prefer to process binary data stored in a little-endian format. Since that format is more efficient on those systems, it is referred to as the "native" binary format.

    On a system supporting only one format of binary storage (generally, that would be big-endian), the terms ’most-efficient’ and ’native format’ are synonymous.

  4. Data items that have the "UNSIGNED"
  5. Packed-decimal (i.e. "USAGE PACKED-DECIMAL", "USAGE COMP-3" or "USAGE COMP-6") data is stored as a series of bytes such that each byte contains two 4-bit fields, referred to as ’nibbles’ (since they comprise half a "byte", they’re just "nibbles" — don’t groan, I don’t just make this stuff up!). Each nibble represents a "9" in the "PICTURE" and each holds a single decimal digit encoded as its binary value (0 = 0000, 1 = 0001, … , 9 = 1001).

    The last byte of a "PACKED-DECIMAL" or "COMP-3" data item will always have its left nibble corresponding to the last "9" in the "PICTURE" and its right nibble reserved as a sign indicator. This sign indicator is always present regardless of whether or not the "PICTURE" included an "S" symbol.

    The first byte of the data item will contain an unused left nibble if the "PICTURE" had an even number of "9" symbols in it.

    The sign indicator will have a value of a hexadecimal A through F. Traditional packed decimal encoding rules call for hexadecimal values of F, A, C or E ("FACE") in the sign nibble to indicate a positive value and B or D to represent a negative value (hexadecimal digits 0-9 are undefined). Testing with a Windows MinGW/GnuCOBOL implementation shows that –– in fact –– hex digit D represents a negative number and any other hexadecimal digit denotes a positive number. Therefore, a "PIC S9(3) COMP-3" packed-decimal field with a value of -15 would be stored internally as a hexadecimal 015D in GnuCOBOL.

    If you attempt to store a negative number into a packed decimal field that has no "S" in its "PICTURE", the absolute value of the negative number will actually be stored.

    "USAGE COMP-6" does not allow for negative values, therefore no sign nibble will be allocated. A "USAGE COMP-6" data item containing an odd number of "9" symbols in its "PICTURE" will leave its leftmost nibble unused.

  6. The "USAGE" specifications "FLOAT-DECIMAL-16" and "FLOAT-DECIMAL-34" will encode data using IEEE 754 "Decimal64" and "Decimal128" format, respectively. The former allows for up to 16 digits of exact precision while the latter offers 34. The phrase "exact precision" is used because the traditional binary renderings of decimal real numbers in a floating-point format ("FLOAT-LONG" and "FLOAT-SHORT", for example) only yield an approximation of the actual value because many decimal fractions cannot be precisely rendered in binary. The Decimal64 and Decimal128 renderings, however, render decimal real numbers in encoded decimal form in much the same way that "PACKED-DECIMAL" renders a decimal integer in digit-by-digit decimal form. The exact manner in which this rendering is performed is complex (Wikipedia has an excellent article on the subject – just search for "Decimal64").
  7. GnuCOBOL stores "FLOAT-DECIMAL-16" and "FLOAT-DECIMAL-34" data items using either Big-Endian or Little-Endian form, whichever is native to the system.
  8. The "USAGE" specifications "FLOAT-LONG" and "FLOAT-SHORT" use the IEEE 754 "Binary64" and "Binary32" formats, respectively. These are binary encodings of real decimal numbers, and as such cannot represent every possible value between the minimum and maximum values in the range for those usages. Wikipedia has an excellent article on the Binary64 and Binary32 encoding schemes – just search on "Binary32" or "Binary64".

    GnuCOBOL stores "FLOAT-LONG" and "FLOAT-SHORT" data items using either Big-Endian or Little-Endian form, whichever is native to the system.

  9. A "USAGE" clause specified at the group item level will apply that "USAGE" to all subordinate data items, except those that themselves have a "USAGE" clause.
  10. The only "USAGE" that is allowed in the report section is "USAGE DISPLAY".


5.9.50. USING

USING Clause Syntax
=======================================================================

 USING identifier-1
 ~~~~~

=======================================================================
This syntax is valid in the following sections:
SCREEN

This clause logically attaches a screen section data item to another data item defined elsewhere in the data division.

  1. When the screen item whose definition this clause is part of is displayed, the value currently in <identifier-1> will be automatically moved into the screen item first.
  2. When the screen item whose definition this clause is part of (or its parent) is accepted, the current contents of the screen item will be saved back to <identifier-1> at the conclusion of the "ACCEPT".
  3. The "FROM" (see FROM), "TO" (see TO), "USING" and "VALUE" (see VALUE) clauses are mutually-exclusive in any screen section data item’s definition.


5.9.51. VALUE

VALUE (Condition Names) Clause Syntax
=======================================================================

 { VALUE IS   } {literal-1 [ THRU|THROUGH literal-2 ]}...
 { ~~~~~      }              ~~~~ ~~~~~~~
 { VALUES ARE }
   ~~~~~~

=======================================================================
VALUE (Other Data Items) Syntax
=======================================================================

 VALUE IS [ ALL ] literal-1
 ~~~~~      ~~~

=======================================================================
This syntax is valid in the following sections:
FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT, SCREEN

The "VALUE" clause is used to define condition names or to assign values (at compilation time) to data items.

  1. The reserved words "ARE" and "IS" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. This clause cannot be specified on the same data item as a "FROM" (see FROM), "TO" (see TO) or "USING" (see USING) clause.
  3. The following points apply to using the "VALUE" clause in the definition of a condition name:
    1. The clauses "VALUE IS" and "VALUES ARE" are interchangeable.
    2. The reserved words "THRU" and "THROUGH" are interchangeable.
    3. See 88-Level Data Items, for a discussion of how this format of "VALUE" is used to create condition names.
    4. See Condition Names, for a discussion of how condition names are used.
  4. The following points apply to using the "VALUE" clause in the definition of any other data item:
    1. In this context, "VALUE" specifies an initial compilation-time value that will be assigned to the storage occupied by the data item in the program object code generated by the compiler.
    2. The "VALUE" clause is ignored on "EXTERNAL" (see EXTERNAL) data items or on any data items defines as subordinate to an "EXTERNAL" data item.
    3. This format of the "VALUE" clause may not be used anywhere in the description of an 01 item (or any of it’s subordinate items) serving as an "FD" or "SD" record description.
    4. If the optional "ALL"
      PIC X(5) VALUE "A"      *> Abbbb
      PIC X(5) VALUE ALL "A"  *> AAAAA
      PIC 9(3) VALUE 1        *> 001
      PIC 9(3) VALUE ALL "1"  *> 111
      
    5. When used in the definition of a screen data item:
      1. A figurative constant may not be supplied as <literal-1>.
      2. Any "FROM" (see FROM), "TO" (see TO) or "USING" (see USING) clause in the same data item’s definition will be ignored.
      3. If there is no picture clause specified, the size of the screen data item will be the length of the <literal-1> value.
      4. If there is no picture clause and the "ALL" option is specified, the "ALL" option will be ignored.
    6. Giving a table an initial, compile-time value is one of the trickier aspects of COBOL data definition. There are basically three standard techniques and a fourth that people familiar with other COBOL implementations but new to GnuCOBOL may find interesting. So, here are the three standard approaches:
      1. Don’t bother worrying about it at compile-time. Use the "INITIALIZE" (see INITIALIZE) to initialize all data item occurrences in a table (at run-time) to their data-type-specific default values (numerics: 0, alphabetic and alphanumerics: spaces).
      2. Initialize small tables at compile time by including a "VALUE" clause on the group item that serves as a parent to the table, as follows:
        05  SHIRT-SIZES          VALUE "S 14M 15L 16XL17".
            10 SHIRT-SIZE-TBL    OCCURS 4 TIMES.
               15 SST-SIZE       PIC X(2).
               15 SST-NECK       PIC 9(2).
        
      3. Initialize tables of almost any size at compilation time by utilizing the "REDEFINES" (see REDEFINES) clause:
        05  SHIRT-SIZE-VALUES.
            10 PIC X(4)          VALUE "S 14".
            10 PIC X(4)          VALUE "M 15".
            10 PIC X(4)          VALUE "L 16".
            10 PIC X(4)          VALUE "XL17".
        05  SHIRT-SIZES          REDEFINES SHIRT-SIZE-VALUES.
            10 SHIRT-SIZE-TBL    OCCURS 4 TIMES.
               15 SST-SIZE       PIC X(2).
               15 SST-NECK       PIC 9(2).
        

        Admittedly, this table is much more verbose than the one shown with a group "VALUE". What is good about this initialization technique, however, is that you can have as many "FILLER" and "VALUE" items as you need for a larger table, and those values can be as long as necessary!

    7. Many COBOL compilers do not allow the use of "VALUE" and "OCCURS" (see OCCURS) on the same data item; additionally, they don’t allow a "VALUE" clause on a data item subordinate to an "OCCURS". GnuCOBOL, however, has neither of these restrictions!

      Observe the following example, which illustrates a fourth manner in which tables may be initialized in GnuCOBOL:

      05  X           OCCURS 6 TIMES.
          10 A        PIC X(1) VALUE '?'.
          10 B        PIC X(1) VALUE '%'.
          10 N        PIC 9(2) VALUE 10.
      

      In this example, all six "A" items will be initialized to "?", all six "B" items will be initialized to "%" and all six "N" items will be initialized to 10. It’s not clear exactly how many times this sort of initialization will be useful, but it’s there if you need it.

  5. The "FROM" (see FROM), "TO" (see TO), "USING" (see USING) and "VALUE" clauses are mutually-exclusive in any screen section data item’s definition.

6. PROCEDURE DIVISION

PROCEDURE DIVISION Syntax
=======================================================================

   PROCEDURE DIVISION [ { USING Subprogram-Argument...     } ]
   ~~~~~~~~~ ~~~~~~~~   { ~~~~~                            }
                        { CHAINING Main-Program-Argument...}
                          ~~~~~~~~
                      [ RETURNING identifier-1 ] .
 [ DECLARATIVES. ]      ~~~~~~~~~
   ~~~~~~~~~~~~
 [ Event-Handler-Routine... . ]

 [ END DECLARATIVES. ]
   ~~~ ~~~~~~~~~~~~
   General-Program-Logic

 [ Nested-Subprogram... ]

 [ END PROGRAM|FUNCTION name-1 ]
   ~~~ ~~~~~~~ ~~~~~~~~

=======================================================================

The PROCEDURE DIVISION of any GnuCOBOL program marks the point where all executable code is written.



6.1. PROCEDURE DIVISION USING

PROCEDURE DIVISION Subprogram-Argument Syntax
=======================================================================

 [ BY { REFERENCE [ OPTIONAL ]                       } ] identifier-1
      { ~~~~~~~~~   ~~~~~~~~                         }
      { VALUE [ [ UNSIGNED ] SIZE IS { AUTO      } ] }
        ~~~~~     ~~~~~~~~   ~~~~    { ~~~~      }
                                     { DEFAULT   }
                                     { ~~~~~~~   }
                                     { integer-1 }

=======================================================================
  1. The reserved words "BY" and "IS" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words have no effect upon the program.
  2. The "USING"
  3. The calling program will pass zero or more data items, known as arguments, to this subprogram — there must be exactly as many <identifier-1> data items specified on the USING clause as the maximum number of arguments the subprogram will ever be passed.
  4. If a subprogram does not expect any arguments, it should not have a "USING" clause specified on it’s procedure division header.
  5. The order in which arguments are defined on the "USING" clause must correspond to the order in which those arguments will be passed to the subprogram by the calling program.
  6. The identifiers specified on the "USING" clause must be defined in the linkage section of the subprogram. No storage is actually allocated for those identifiers in the subprogram as the actual storage for them will exist in the calling program.
  7. A GnuCOBOL subprogram expects that all arguments to it will be one of two things:

    In the case of the former, the "USING" clause on the procedure division header should describe the argument via the "BY REFERENCE"

  8. "BY REFERENCE" is the assumed default for the first "USING" argument should no "BY" clause be specified for it. Subsequent arguments will assume the "BY" specification of the argument prior to them should they lack a "BY" clause of their own.
  9. Changes made by a subprogram to the value of an argument specified on the "USING" clause will "be visible" to the calling program only if "BY REFERENCE" was explicitly specified or implicitly assumed for the argument on the subprogram’s procedure division header and the argument was passed to the subprogram "BY REFERENCE" by the calling program. See Subprogram Arguments, for additional information on the mechanics of how arguments are passed to subprograms.
  10. The optional "SIZE" clause allows you to specify the number of bytes a "BY VALUE" argument will occupy, with "SIZE DEFAULT" specifying 4 bytes (this is the default if no "SIZE" clause is used), "SIZE AUTO" specifying the size of the argument in the calling program and "SIZE <integer-1>" specifying a specific byte count.
  11. The optional "UNSIGNED" keyword, legal only if "SIZE AUTO" or "SIZE <integer-1>" are coded, will add the "unsigned" attribute to the argument’s specification in the C-language function header code generated for the subprogram. While not of any benefit when the calling program is a GnuCOBOL program, this can improve compatibility with a C-language calling program.
  12. The "OPTIONAL"


6.2. PROCEDURE DIVISION CHAINING

PROCEDURE DIVISION Main-Program-Argument Syntax
=======================================================================

 [ BY REFERENCE ] [ OPTIONAL ] identifier-1
      ~~~~~~~~~     ~~~~~~~~

=======================================================================
  1. "PROCEDURE DIVISION CHAINING" may only be coded in a main program (that is, the first program executed when a compiled GnuCOBOL compilation unit is executed). It cannot be used in any form of subprogram.
  2. The "CHAINING" clause defines arguments that will be passed to a main program from the operating system. The argument identifiers specified on the CHAINING clause will be populated by character strings comprised of the parameters specified to the program on the command line that executed it, as follows:
    1. When a GnuCOBOL program is executed from a command-line, the complete command line text will be broken into a series of "tokens", where each token is identified as being a word separated from the others in the command text by at least one space. For example, if the command line was /usr/local/myprog THIS IS A TEST, there will be five tokens identified by the operating system — "/usr/local/myprog", "THIS", "IS", "A" and "TEST".
    2. Multiple space-delimited tokens may be treated as a single token by enclosing them in quotes. For example, there are only three tokens generated from the command line C:\Pgms\myprog.exe "THIS IS A" TEST — "C:\Pgms\myprog.exe", "THIS IS A" and "TEST". When quote characters are used to create multi-word tokens, the quote characters themselves are stripped from the token’s value.
    3. Once tokens have been identified, the first (the command) will be discarded; the rest will be stored into the "CHAINING" arguments when the program begins execution, with the 2nd token going to the 1st argument, the 3rd token going to the 2nd argument and so forth.
    4. If there are more tokens than there are arguments, the excess tokens will be discarded.
    5. If there are fewer tokens than there are arguments, the excess arguments will be initialized as if the "INITIALIZE <identifier-1>" (see INITIALIZE) statement were executed.
    6. All identifiers specified on the CHAINING clause should be defined as PIC X, PIC A, group items (which are treated implicitly as PIC X) or as PIC 9 USAGE DISPLAY. The use of USAGE BINARY (or the like) data items as CHAINING arguments is not recommended as all command-line tokens will be retained in their original character form as they are moved into the argument data items.
    7. If an argument identifier is smaller in storage size than the token value to be stored in it, the right-most excess characters of the token value will be truncated as the value is moved in. Any JUSTIFIED RIGHT clause on such an argument identifier will be ignored.
    8. If an argument is larger in storage size than the token value to be stored in it, the token value will be moved into the argument identifier in a left-justified manner. unmodified-modified byte positions in the identifier will be space filled, unless the argument identifier is defined as PIC 9 USAGE DISPLAY, in which case unmodified bytes will be filled with "0" characters from the systems native character set.

      This behaviour when the argument is defined as "PIC 9" may be unacceptable, as an argument defined as "PIC 9(3)" but passed in a value of "1" from the command line will receive a value of "100", not "001". Consider defining "numeric" command line arguments as "PIC X" and then using the "NUMVAL" intrinsic function (see NUMVAL) function to determine the proper numeric value.



6.3. PROCEDURE DIVISION RETURNING

PROCEDURE DIVISION RETURNING Syntax
=======================================================================

 RETURNING identifier-1
 ~~~~~~~~~

=======================================================================
  1. The "RETURNING" clause is optional within a subroutine, as not all subroutines return a value to their caller.
  2. The "RETURNING" clause is mandatory within a user-defined function, as all such must return a numeric result.
  3. The <identifier-1> data item should be defined as a USAGE BINARY-LONG data item.
  4. Main programs that wish to "pass back" a return code value to the operating system when they exit do not use RETURNING - they do so simply by MOVEing a value to the "RETURN-CODE" special register.
  5. This is not the only mechanism that a subprogram may use to pass a value back to it’s caller. Other possibilities are:
    1. The subprogram may modify any argument that is specified as "BY REFERENCE" on it’s PROCEDURE DIVISION header. Whether the calling program can actually "see" any modifications depends upon how the calling program passed the argument to the subprogram. See CALL, for more information.
    2. A data item with the "GLOBAL" (see GLOBAL) attribute specified in it’s description in the calling program is automatically visible to and updatable by a subprogram nested with the calling program. See Independent vs Contained vs Nested Subprograms, for more information on subprogram nesting.
    3. A data item defined with the "EXTERNAL" (see EXTERNAL) attribute in a subprogram and the calling program (same name in both programs) is automatically visible to and updatable by both programs, even if those programs are compiled separately from one another.


6.4. PROCEDURE DIVISION Sections and Paragraphs

The procedure division is the only one of the COBOL divisions that allows you to create your own sections and paragraphs. These are collectively referred to as ’Procedures Procedure names are optional in the procedure division and — when used — are named entirely according to the needs and whims of the programmer.

Procedure names may be up to thirty one (31) characters long and may consist of letters, numbers, dashes and underscores. A procedure name may neither begin nor end with a dash (-) or underscore (_) character. This means that "Main", "0100-Read-Transaction" and "17" are all perfectly valid procedure names.

There are three circumstances under which the use of certain GnuCOBOL statements or options will require the specification of procedures. These situations are:

  1. When "DECLARATIVES" (see DECLARATIVES) are specified.
  2. When the "ENTRY" statement (see ENTRY) is being used.
  3. When any procedure division statement that references procedures is used. These statements are:


6.5. DECLARATIVES

DECLARATIVES Syntax
=======================================================================

section-name-1 SECTION.

 USE { [ GLOBAL ] AFTER STANDARD { EXCEPTION } PROCEDURE ON { INPUT       } }
 ~~~ {   ~~~~~~                  { ~~~~~~~~~ }              { ~~~~~       } }
     {                           { ERROR     }              { OUTPUT      } }
     {                             ~~~~~                    { ~~~~~~      } }
     {                                                      { I-O         } }
     { FOR DEBUGGING ON { procedure-name-1           }      { ~~~         } }
     {     ~~~~~~~~~    { ALL PROCEDURES             }      { EXTEND      } }
     {                  { ~~~ ~~~~~~~~~~             }      { ~~~~~~      } }
     {                  { REFERENCES OF identifier-1 }      { file-name-1 } }
     {                                                                      }
     { [ GLOBAL ] BEFORE REPORTING identifier-2                             }
     {   ~~~~~~   ~~~~~~ ~~~~~~~~~                                          }
     {                                                                      }
     { AFTER EC|{EXCEPTION CONDITION}                                       }
             ~~  ~~~~~~~~~ ~~~~~~~~~

The "AFTER EXCEPTION CONDITION"


=======================================================================
  1. The reserved words "AFTER", "FOR", "ON", "PROCEDURE" and "STANDARD" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. "EC" and "EXCEPTION CONDITION" are interchangeable.
  3. The declaratives area may contain any number of declarative procedures, but no two declarative procedures should be coded to trap the same event.
  4. The following points apply to the "USE BEFORE REPORTING"
    1. <identifier-2> must be a report group.
    2. At run-time, the declaratives procedure will be executed prior to the processing of the specified report group’s presentation; within the procedure you may take either of the following actions:
      • You may adjust the value(s) of any items referenced in "SUM" (see SUM) or "SOURCE" (see SOURCE) clauses in the report group.
      • You may execute the "SUPPRESS" (see SUPPRESS) statement to squelch the presentation of the specified report group altogether. Note that you will be suppressing this one specific instance of that group’s presentation and not all of them.
  5. The following points apply to the "USE FOR DEBUGGING"
    1. This clause allows you to define a declarative procedure that will be invoked whenever…
      • …<identifier-1> is referenced on any statement.
      • …<procedure-name-1> is executed.
      • …any procedure is executed ("ALL PROCEDURES").
    2. A "USE FOR DEBUGGING" declarative procedure will be ignored at compilation time unless "WITH DEBUGGING MODE" is specified in the "SOURCE-COMPUTER" (see SOURCE-COMPUTER) paragraph. Neither the compiler’s "-fdebugging-line" switch
    3. Any "USE FOR DEBUGGING" declarative procedures will be ignored at execution time unless the
    4. The typical use of a "USE FOR DEBUGGING" declarative procedure is to display the "DEBUG-ITEM" special register , which will be implicitly and automatically created in your program for you if "WITH DEBUGGING MODE" is active.

      The structure of DEBUG-ITEM will be as follows:

      01  DEBUG-ITEM.
          05 DEBUG-LINE      PIC X(6).
          05 FILLER          PIC X(1) VALUE SPACE.
          05 DEBUG-NAME      PIC X(31).
          05 FILLER          PIC X(1) VALUE SPACE.
          05 DEBUG-SUB-1     PIC S9(4) SIGN LEADING SEPARATE.
          05 FILLER          PIC X(1) VALUE SPACE.
          05 DEBUG-SUB-2     PIC S9(4) SIGN LEADING SEPARATE.
          05 FILLER          PIC X(1) VALUE SPACE.
          05 DEBUG-SUB-3     PIC S9(4) SIGN LEADING SEPARATE.
          05 FILLER          PIC X(1) VALUE SPACE.
          05 DEBUG-CONTENTS  PIC X(31).
      

      where…

      "DEBUG-LINE"

      … is the program line number of the statement that triggered the declaratives procedure.

      "DEBUG-NAME"

      … is the procedure name or identifier name that triggered the declaratives procedure.

      "DEBUG-SUB-1"

      … is the first subscript value (if any) for the reference of the identifier that triggered the declaratives procedure.

      "DEBUG-SUB-2"

      … is the second subscript value (if any) for the reference of the identifier that triggered the declaratives procedure.

      "DEBUG-SUB-3"

      … is the third subscript value (if any) for the reference of the identifier that triggered the declaratives procedure.

      "DEBUG-CONTENTS"

      … is a (brief) statement of the manner in which the procedure that triggered the declaratives procedure was executed or the first 31 characters of the value of the identifier whose reference triggered the declaratives procedure (the value after the statement was executed).

  6. The "USE AFTER STANDARD ERROR PROCEDURE"
  7. The "GLOBAL" (see GLOBAL) option, if used, allows a declarative procedure to be used across the program containing the "USE" statement and any subprograms nested within that program.
  8. Declarative procedures may not reference any other procedures defined outside the scope of DECLARATIVES.


6.6. Table References

For example, observe the following data structure which defines a 4 column by 3 row grid of characters:

01  GRID.
     05 GRID-ROW OCCURS 3 TIMES.
        10 GRID-COLUMN OCCURS 4 TIMES.
            15 GRID-CHARACTER       PIC X(1).

If the structure contains the following grid of characters:

A B C D
E F G H
I J K L

Then "GRID-CHARACTER (2, 3)" references the "G" and "GRID-CHARACTER (3, 2)" references the "J".

Subscripts may be specified as numeric (integer) literals, numeric (integer) data items, data items created with any of the picture-less integer "USAGE" (see USAGE) specifications, "USAGE INDEX" data items or arithmetic expressions resulting in a non-zero integer value.

In the above examples, a comma is used as a separator character between the two subscript values; semicolons (";") are also valid subscript separator characters, as are spaces! The use of a comma or semicolon separator in such a situation is technically optional, but by convention most COBOL programmers use one or the other. The use of no separator character (other than a space) is not recommended, even though it is syntactically correct, as this practice can lead to programmer-unfriendly code. It isn’t too difficult to read and understand "GRID-CHARACTER(2 3)", but it’s another story entirely when trying to comprehend "GRID-CHARACTER(I + 1 J / 3)" (instead of "GRID-CHARACTER(I + 1, J / 3)"). The compiler accepts it, but too much of this would make my head hurt.



6.7. Qualification of Data Names

To see qualification at work, observe the following segments of two data records defined in a COBOL program:

01  EMPLOYEE.                     01  CUSTOMER.
    05 MAILING-ADDRESS.               05 MAILING-ADDRESS.
       10 STREET        PIC X(35).       10 STREET        PIC X(35).
       10 CITY          PIC X(15).       10 CITY          PIC X(15).
       10 STATE         PIC X(2).        10 STATE         PIC X(2).
       10 ZIP-CODE.                      10 ZIP-CODE.
          15 ZIP-CODE-5 PIC 9(5).           15 ZIP-CODE-5 PIC 9(5).
          15 FILLER     PIC X(4).           15 FILLER     PIC X(4).

Now, let’s deal with the problem of setting the CITY portion of an EMPLOYEEs MAILING-ADDRESS to "Philadelphia". Clearly, "MOVE 'Philadelphia' TO CITY" cannot work because the compiler will be unable to determine which of the two CITY fields you are referring to.

In an attempt to correct the problem, we could qualify the reference to CITY as "MOVE 'Philadelphia' TO CITY OF MAILING-ADDRESS".

Unfortunately that too is insufficient because it still insufficiently specifies which CITY is being referenced. To truly identify which specific CITY you want, you’d have to code "MOVE 'Philadelphia' TO CITY OF MAILING-ADDRESS OF EMPLOYEE".

Now there can be no confusion as to which CITY is being changed. Fortunately, you don’t need to be quite so specific; COBOL allows intermediate and unnecessary qualification levels to be omitted. This allows "MOVE 'Philadelphia' TO CITY OF EMPLOYEE" to do the job nicely.

If you need to qualify a reference to a table, do so by coding something like "<identifier-1> OF <identifier-2> ( subscript(s) )".

The reserved word "IN" may be used in lieu of "OF".



6.8. Reference Modifiers

Reference Modifier (Format 1) Syntax
=======================================================================

 identifier-1 [ OF|IN identifier-2 ] [ (subscript...) ] (start:[ length ])
                ~~ ~~

=======================================================================
Reference Modifier (Format 2) Syntax
=======================================================================

 intrinsic-function-reference (start:[ length ])

=======================================================================

The <start> value indicates the starting character position being referenced (character position values start with 1, not 0 as is the case in some programming languages) and <length> specifies how many characters are wanted.

If no <length> is specified, a value equivalent to the remaining character positions from <start> to the end of <identifier-1> or to the end of the value returned by the function will be assumed.

Both <start> and <length> may be specified as integer numeric literals, integer numeric data items or arithmetic expressions with an integer value.

Here are a few examples:

"CUSTOMER-LAST-NAME (1:3)"

References the first three characters of CUSTOMER-LAST-NAME.

"CUSTOMER-LAST-NAME (4:)"

References all character positions of CUSTOMER-LAST-NAME from the fourth onward.

"FUNCTION CURRENT-DATE (5:2)"

References the current month as a 2-digit number in character form. See CURRENT-DATE, for more information.

"Hex-Digits (Nibble + 1:1)"

Assuming that "Nibble" is a numeric data item with a value in the range 0-15, and Hex-Digits is a "PIC X(16)" item with a value of "0123456789ABCDEF", this converts that numeric value to a hexadecimal digit.

"Table-Entry (6) (7:5)"

References characters 7 through 11 (5 characters in total) in the 6th occurrence of Table-Entry.


Reference modification may be used anywhere an identifier is legal, including serving as the receiving field of statements like "MOVE" (see MOVE), "STRING" (see STRING) and "ACCEPT" (see ACCEPT), to name a few.



6.9. Arithmetic Expressions

Arithmetic-Expression Syntax
=======================================================================

 Unary-Expression-1 { **|^ } Unary-Expression-2
                    {  *|/ }
                    {  +|- }

=======================================================================
Unary-Expression Syntax
=======================================================================

 { [ +|- ] { ( Arithmetic-Expression-1 )          } }
 {         { [ LENGTH OF ] { identifier-1       } } }
 {         {   ~~~~~~ ~~   { literal-1          } } }
 {         {               { Function-Reference } } }
 { Arithmetic-Expression-2                          }

=======================================================================

In complex expressions composed of multiple operators and operands, a precedence of operation applies whereby those operations having a higher precedence are computed first before operations with a lower precedence.

As is the case in almost any other programming language, the programmer is always free to use pairs of parenthesis to enclose sub-expressions of complex expressions that are to be evaluated before other sub-expressions rather than let operator precedence dictate the sequence of evaluation.

In highest to lowest order of precedence, here is a discussion of each category of operation:

Level 1 (Highest) — Unary Sign Specification ("+" and "-" with a single argument)

The unary "minus" (-) operator returns the arithmetic negation of its single argument, effectively returning as its value the product of its argument and -1.

The unary "plus" (+) operator returns the value of its single argument, effectively returning as its value the product of its argument and +1.

Level 2 — Exponentiation ("**" or "^")

The value of the left argument is raised to the power indicated by the right argument. Non-integer powers are allowed. The "^" and "**" operators are both supported to provide compatibility with programs written for other COBOL implementations.

Level 3 — Multiplication ("*") and division ("/")

The "*" operator computes the product of the left and right arguments while the "/" operator computes the value of the left argument divided by the value of the right argument. If the right argument has a value of zero, expression evaluation will be prematurely terminated before a value is generated. This may cause program failure at run-time.

A sequence of multiple 3rd-level operations ("A * B / C", for example) will evaluate in strict left-to-right sequence if no parenthesis are used to control the order of evaluation.

Level 4 — Addition ("+") or subtraction ("+")

The "+" operator calculates the sum of the left and right arguments while the "-" operator computes the value of the right argument subtracted from that of the left argument.

A sequence of multiple 4th-level operations ("A - B + C", for example) will evaluate in strict left-to-right sequence if no parenthesis are used to control the order of evaluation.


The syntactical rules of COBOL, allowing a dash (-) character in data item names, can lead to some ambiguity.

01  C        PIC 9 VALUE 5.
01  D        PIC 9 VALUE 2.
01  C-D      PIC 9 VALUE 7.
01  I        PIC 9 VALUE 0.
…
COMPUTE I=C-D+1

The "COMPUTE" (see COMPUTE) statement will evaluate the arithmetic expression "C-D+1" and then save that result in "I".

What value will be stored in "I"? The number 4, which is the result of subtracting the value of "D" (2) from the value of "C" (5) and then adding 1? Or, will it be the number 8, which is the value of adding 1 to the value of data item "C-D" (7)?

The right answer is 8 — the value of data item "C-D" plus 1! Hopefully, that was the intended result.

The GnuCOBOL compiler actually went through the following decision-making logic when generating code for the "COMPUTE" Statement:

  1. Is there a data item named "C-D" defined? If so, use its value for the character sequence "C-D".
  2. If there is no "C-D" data item, then are there "C" and "D" data items? If not, the "COMPUTE" statement is in error. If there are, however, then code will be generated to subtract the value of "D" from "C" and add 1 to the result.

Had there been at least one space to the left and/or the right of the "-", there would have been no ambiguity — the compiler would have been forced to use the individual "C" and "D" data items.

To avoid any possible ambiguity, as well as to improve program readability, it’s considered good COBOL programming practice to always code at least one space to both the left and right of every operator in arithmetic expressions as well as the "=" sign on a COMPUTE.

Here are some examples of how the precedence of operations affects the results of arithmetic expressions (all examples use numeric literals, to simplify the discussion).

ExpressionResultNotes
3 * 4 + 113* has precedence over +
4 * 2 ^ 3 - 10222^3 is 8 (^ has precedence over *), times 4 is 32, minus 10 is 22.
(4 * 2) ^ 3 - 10502Parenthesis provide for a recursive application of the arithmetic expression rules, effectively allowing you to alter the precedence of operations. 4 times 2 is 8 (the use of parenthesis "trumps" the exponentiation operator, so the multiplication happens first); 8 ^ 3 is 512, minus 10 is 502.
5 / 2.5 + 7 * 2 - 1.1515.35Integer and non-integer operands may be freely intermixed

Of course, arithmetic expression operands may be numeric data items (any USAGE except POINTER or PROGRAM POINTER) as well as numeric literals.



6.10. Conditional Expressions

There are seven types of conditional expressions, as discussed in the following sections.



6.10.1. Condition Names

05  SHIRT-SIZE               PIC 99V9.
    88 TINY                  VALUE 0 THRU 12.5
    88 XS                    VALUE 13 THRU 13.5.
    88 S                     VALUE 14, 14.5.
    88 M                     VALUE 15, 15.5.
    88 L                     VALUE 16, 16.5.
    88 XL                    VALUE 17, 17.5.
    88 XXL                   VALUE 18, 18.5.
    88 XXXL                  VALUE 19, 19.5.
    88 VERY-LARGE            VALUE 20 THRU 99.9.

The condition names "TINY", "XS", "S", "M", "L", "XL", "XXL", "XXXL" and "VERY-LARGE" will have TRUE or FALSE values based upon the values within their parent data item (SHIRT-SIZE).

A program wanting to test whether or not the current "SHIRT-SIZE" value can be classified as "XL" could have that decision coded as a combined condition (the most complex type of conditional expression), as either:

IF SHIRT-SIZE = 17 OR SHIRT-SIZE = 17.5

- or -

IF SHIRT-SIZE = 17 OR 17.5

Or it could simply utilize the condition name XL as follows:

IF XL


6.10.2. Class Conditions

Class-Condition Syntax
=======================================================================

 identifier-1 IS [ NOT ] { NUMERIC          }
                   ~~~   { ~~~~~~~          }
                         { ALPHABETIC       }
                         { ~~~~~~~~~~       }
                         { ALPHABETIC-LOWER }
                         { ~~~~~~~~~~~~~~~~ }
                         { ALPHABETIC-UPPER }
                         { ~~~~~~~~~~~~~~~~ }
                         { OMITTED          }
                         { ~~~~~~~          }
                         { class-name-1     }

=======================================================================
  1. The "NUMERIC"
  2. The "ALPHABETIC"
  3. The "ALPHABETIC-LOWER"
  4. The "NOT" option reverses the TRUE/FALSE value of the condition.
  5. Note that what constitutes a "letter" (or upper/lower case too, for that manner) may be influenced through the use of "CHARACTER CLASSIFICATION" specifications in the "OBJECT-COMPUTER" (see OBJECT-COMPUTER) paragraph.
  6. Only data items whose "USAGE" (see USAGE) is either explicitly or implicitly defined as "DISPLAY" may be used in "NUMERIC" or any of the "ALPHABETIC" class conditions.
  7. Some COBOL implementations disallow the use of group items or "PIC A" items with "NUMERIC" class conditions and the use of "PIC 9" items with "ALPHABETIC" class conditions. GnuCOBOL has no such restrictions.
  8. The "OMITTED"

The <class-name-1> option allows you to test for a user-defined class. Here’s an example. First, assume the following "SPECIAL-NAMES" (see SPECIAL-NAMES) definition of the user-defined class "Hexadecimal":

SPECIAL-NAMES.
    CLASS Hexadecimal IS '0' THRU '9', 'A' THRU 'F', 'a' THRU 'f'.

Now observe the following code, which will execute the "150-Process-Hex-Value" procedure if "Entered-Value" contains nothing but valid hexadecimal digits:

    IF Entered-Value IS Hexadecimal
        PERFORM 150-Process-Hex-Value
    END-IF


6.10.3. Sign Conditions

Sign-Condition Syntax
=======================================================================

 identifier-1 IS [ NOT ] { POSITIVE }
                   ~~~   { ~~~~~~~~ }
                         { NEGATIVE }
                         { ~~~~~~~~ }
                         { ZERO     }
                           ~~~~

=======================================================================
  1. A "POSITIVE"
  2. A "ZERO"
  3. The "NOT" option reverses the TRUE/FALSE value of the condition.


6.10.4. Switch-Status Conditions

Here are the relevant sections of code in a program named "testprog", which is designed to simply announce if SWITCH-1 is on:

…
ENVIRONMENT DIVISION.
SPECIAL-NAMES.
    SWITCH-1 ON STATUS IS Switch-1-Is-ON.
…
PROCEDURE DIVISION.
…
    IF Switch-1-Is-ON
        DISPLAY "Switch 1 Is On"
    END-IF
…

the following are two different command window sessions — the left on a Unix/Cygwin/OSX system and the right on a windows system — that will set the switch on and then execute the "testprog" program. Notice how the message indicating that the program detected the switch was set is displayed in both examples:

$ COB_SWITCH_1=ON           C:>SET COB_SWITCH_1=ON
$ export COB_SWITCH_1       C:>testprog
$ ./testprog                Switch 1 Is On
Switch 1 Is On              C:>
$


6.10.5. Relation Conditions

Relation-Condition Syntax
=======================================================================

 { identifier-1            } IS [ NOT ] RelOp { identifier-2            }
 { literal-1               }      ~~~         { literal-2               }
 { arithmetic-expression-1 }                  { arithmetic-expression-2 }
 { index-name-1            }                  { index-name-2            }

=======================================================================
RelOp Syntax
=======================================================================

 { EQUAL TO                 }
 { ~~~~~                    }
 { EQUALS                   }
 { ~~~~~~                   }
 { GREATER THAN             }
 { ~~~~~~~                  }
 { GREATER THAN OR EQUAL TO }
 { ~~~~~~~      ~~ ~~~~~    }
 { LESS THAN                }
 { ~~~~                     }
 { LESS THAN OR EQUAL TO    }
 { ~~~~      ~~ ~~~~~       }
 { =                        }
 { >                        }
 { >=                       }
 { <                        }
 { <=                       }

=======================================================================
  1. When comparing one numeric value to another, the "USAGE" (see USAGE) and number of significant digits in either value are irrelevant as the comparison is performed using the actual algebraic values.
  2. When comparing strings, the comparison is made based upon the program’s collating sequence. When the two string arguments are of unequal length, the shorter is assumed to be padded (on the right) with a sufficient number of spaces as to make the two strings of equal length. String comparisons take place on a corresponding character-by-character basis, left to right, until the TRUE/FALSE value for the relation test can be established. Characters are compared according to their relative position in the program’s "COLLATING SEQUENCE" (as defined in "SPECIAL-NAMES" (see SPECIAL-NAMES)), not according to the bit-pattern values the characters have in storage.
  3. By default, the program’s "COLLATING SEQUENCE" will, however, be based entirely on the bit-pattern values of the various characters.
  4. There is no functional difference between using the wordy version ("IS EQUAL TO", "IS LESS THAN", …) versus the symbolic version ("=", "<", …) of the actual relation operators.


6.10.6. Combined Conditions

Combined Condition Syntax
=======================================================================

 [ ( ] Condition-1 [ ) ] { AND } [ ( ] Condition-2 [ ) ]
                         { ~~~ }
                         { OR  }
                         { ~~  }

=======================================================================
  1. If either condition has a value of TRUE, the result of "OR"
  2. In order for "AND"
  3. When chaining multiple, similar conditions together with the same operator (OR/AND), and left or right arguments have common subjects, it is possible to abbreviate the program code. For example:
    IF ACCOUNT-STATUS = 1 OR ACCOUNT-STATUS = 2 OR ACCOUNT-STATUS = 7
    

    Could be abbreviated as:

    IF ACCOUNT-STATUS = 1 OR 2 OR 7
    
  4. Just as multiplication takes precedence over addition in arithmetic expressions, so does "AND" take precedence over "OR" in combined conditions. Use parenthesis to change this precedence, if necessary. For example:
    "FALSE AND FALSE OR TRUE AND TRUE"

    Evaluates to TRUE

    "(FALSE AND FALSE) OR (TRUE AND TRUE)"

    Evaluates to TRUE (since AND has precedence over OR) - this is identical to the previous example

    "(FALSE AND (FALSE OR TRUE)) AND TRUE"

    Evaluates to FALSE



6.10.7. Negated Conditions

Negated Condition Syntax
=======================================================================

 NOT Condition-1
 ~~~

=======================================================================
  1. The "NOT" operator has the highest precedence of all logical operators, just as a unary minus sign (which "negates" a numeric value) is the highest precedence arithmetic operator.
  2. Parenthesis must be used to explicitly signify the sequence in which conditions are evaluated and processed if the default precedence isn’t desired. For example:
    "NOT TRUE AND FALSE AND NOT FALSE"

    Evaluates to FALSE AND FALSE AND TRUE which evaluates to FALSE

    "NOT (TRUE AND FALSE AND NOT FALSE)"

    Evaluates to NOT (FALSE) which evaluates to TRUE

    "NOT TRUE AND (FALSE AND NOT FALSE)"

    Evaluates to FALSE AND (FALSE AND TRUE) which evaluates to FALSE



6.11. Use of Periods

MOVE SPACES TO Employee-Address
ADD 1 TO Record-Counter
DISPLAY "Record-Counter=" Record-Counter

Some COBOL statements have a "scope of applicability" associated with them where one or more other statements can be considered to be part of or related to the statement in question. An example of such a situation might be the following, where the interest on a loan is being calculated and displayed — 4% interest if the loan balance is under $10000 and 4.5% otherwise (WARNING – the following code has an error!):

IF Loan-Balance < 10000
    MULTIPLY Loan-Balance BY 0.04 GIVING Interest
ELSE
    MULTIPLY Loan-Balance BY 0.045 GIVING Interest
DISPLAY "Interest Amount = " Interest

In this example, the IF statement actually has a scope that can include two sets of associated statements – one set to be executed when the "IF" (see IF) condition is TRUE and another if it is FALSE.

Unfortunately, there’s a problem with the above. A human being looking at that code would probably infer that the "DISPLAY" (see DISPLAY) statement, because of its lack of indentation, is to be executed regardless of the TRUE/FALSE value of the "IF" condition. Unfortunately, the GnuCOBOL compiler (or any other COBOL compiler for that matter) won’t see it that way because it really couldn’t care less what sort of indentation, if any, is used. In fact, any COBOL compiler would be just as happy to see the code written like this:

IF Loan-Balance < 10000 MULTIPLY Loan-balance
BY 0.04 GIVING Interest ELSE MULTIPLY
Loan-Balance BY 0.045 GIVING Interest DISPLAY
"Interest Amount = " Interest

So how then do we inform the compiler that the "DISPLAY" statement is outside the scope of the "IF"?

That’s where sentences come in.

A COBOL ’Sentence

IF Loan-Balance < 10000
    MULTIPLY Loan-Balance BY 0.04 GIVING Interest
ELSE
    MULTIPLY Loan-Balance BY 0.045 GIVING Interest.
DISPLAY "Interest Amount = " Interest

See the period at the end of the second "MULTIPLY" (see MULTIPLY)? That is what terminates the scope of the "IF", thus making the "DISPLAY" statement’s execution completely independent of the TRUE/FALSE status of the "IF".



6.12. Use of VERB/END-VERB Constructs

Unfortunately, this caused some problems. Take a look at this code:

IF A = 1
    IF B = 1
        DISPLAY "A & B = 1"
ELSE *> This ELSE has a problem!
    IF B = 1
        DISPLAY "A NOT = 1 BUT B = 1"
    ELSE
        DISPLAY "NEITHER A NOR B = 1".

The problem with this code is that indentation — so critical to improving the human-readability of a program — can provide an erroneous view of the logical flow. An "ELSE" is always associated with the most-recently encountered "IF"; this means the emphasized "ELSE" will be associated with the "IF B = 1" statement, not the "IF A = 1" statement as the indentation would appear to imply.

This sort of problem led to a band-aid solution — the "NEXT SENTENCE"

IF A = 1
    IF B = 1
        DISPLAY "A & B = 1"
    ELSE
        NEXT SENTENCE
ELSE
    IF B = 1
        DISPLAY "A NOT = 1 BUT B = 1"
    ELSE
        DISPLAY "NEITHER A NOR B = 1".

The "NEXT SENTENCE" clause informs the compiler that if the "B = 1" condition is false, control should fall into the first statement that follows the next period.

With the 1985 standard for COBOL, a much more elegant solution was introduced. Any COBOL ’Verb

IF A = 1
    IF B = 1
        DISPLAY "A & B = 1"
    END-IF
ELSE
    IF B = 1
        DISPLAY "A NOT = 1 BUT B = 1"
    ELSE
        DISPLAY "NEITHER A NOR B = 1".

This new facility made the period almost obsolete, as our program segment would probably be coded like this today:

IF A = 1
    IF B = 1
        DISPLAY "A & B = 1"
    END-IF
ELSE
    IF B = 1
        DISPLAY "A NOT = 1 BUT B = 1"
    ELSE
        DISPLAY "NEITHER A NOR B = 1"
    END-IF
END-IF

COBOL (GnuCOBOL included) still requires that each procedure division paragraph contain at least one sentence if there is any executable code in that paragraph, but a popular coding style is now to simply code a single period right before the end of each paragraph.

The standard for the COBOL language shows the various "END-verb" clauses are optional because using a period as a scope-terminator remains legal.

If you will be porting existing code over to GnuCOBOL, you’ll find it an accommodating facility capable of conforming to whatever language and coding standards that code is likely to use. If you are creating new GnuCOBOL programs, however, I would strongly counsel you to use the "END-verb" structures in those programs.



6.13. Concurrent Access to Files

Not all GnuCOBOL implementations support file sharing and record-locking options. Whether they do or not depends upon the operating system they were built for and the build options that were used when the specific GnuCOBOL implementation was generated.



6.13.1. File Sharing

Any limitations imposed on a successful "OPEN" (see OPEN) will remain in place until your program either issues a "CLOSE" (see CLOSE) against the file or the program terminates.

File sharing is controlled through the use of a "SHARING"

    SHARING WITH { ALL OTHER }
    ~~~~~~~      { ~~~       }
                 { NO OTHER  }
                 { ~~        }
                 { READ ONLY }
                   ~~~~ ~~~~

This clause may be used either in the file’s "SELECT" statement (see SELECT), on the "OPEN" statement (see OPEN) which initiates your program’s use of the file, or both. If a "SHARING" option is specified in both places, the specifications made on the "OPEN" statement will take precedence over those from the "SELECT" statement.

Here are the meanings of the three options:

"ALL OTHER"

When your program opens a file with this sharing option in effect, no restrictions will be placed on other programs attempting to "OPEN" the file after your program did. This is the default sharing mode.

"NO OTHER"

When your program opens a file with this sharing option in effect, your program announces that it is unwilling to allow any other program to have any access to the file as long as you are using that file; "OPEN" attempts made in other programs will fail with a file status of 37 ("PERMISSION DENIED") until such time as you "CLOSE" (see CLOSE) the file.

"READ ONLY"

Opening a file with this sharing option indicates you are willing to allow other programs to "OPEN" the file for input while you have it open. If they attempt any other "OPEN", theirs will fail with a file status of 37. Of course, your program may fail if someone else got to the file first and opened it with a sharing option that imposed file-sharing limitations.


If the "SELECT" of a file is coded with a "FILE STATUS" clause, "OPEN" failures — including those induced by sharing failures — will be detectable by the program and a graceful recovery (or at least a graceful termination) will be possible. If no such clause was coded, however, a runtime message will be issued and the program will be terminated.



6.13.2. Record Locking

The various I/O statements your program can execute are capable of imposing limitations on access by other concurrently-executing programs to the file record they just accessed. These limitations are syntactically imposed by placing a lock on the record using a "LOCK" clause. Other records in the file remain available, assuming that file-sharing limitations imposed at the time the file was opened didn’t prevent access to the entire file.

  1. If the GnuCOBOL build you are using was configured to use the Berkeley Database (BDB) package for indexed file I/O, record locking will be available by using the
  2. If the "SELECT" (see SELECT) statement or file "OPEN" (see OPEN) specifies "SHARING WITH NO OTHER", record locking will be disabled.
  3. If the file’s "SELECT" contains a "LOCK MODE IS AUTOMATIC"
  4. If the file’s "SELECT" contains a "LOCK MODE IS MANUAL"
  5. If the "LOCK ON" clause is specified in the file’s "SELECT", locks (either automatically or manually acquired) will continue to accumulate as more and more records are read, until they are explicitly released. This is referred to as ’multiple record locking

    Locks acquired vie multiple record locking remain in-effect until the program holding the lock…

  6. If the "LOCK ON"
  7. A "LOCK" clause, which may be coded on a "READ" (see READ), "REWRITE" (see REWRITE) or "WRITE" statement (see WRITE) looks like this:
        { IGNORING LOCK    }
        { ~~~~~~~~ ~~~~    }
        { WITH [ NO ] LOCK }
        {        ~~   ~~~~ }
        { WITH KEPT LOCK   }
        {      ~~~~ ~~~~   }
        { WITH IGNORE LOCK }
        {      ~~~~~~ ~~~~ }
        { WITH WAIT        }
               ~~~~
    

    The "WITH [ NO ] LOCK" option is the only one available to "REWRITE" or "WRITE" statements.

    The meanings of the various record locking options are as follows:

    "IGNORING LOCK"
    "WITH IGNORE LOCK"

    These options (which are synonymous) inform GnuCOBOL that any locks held by other programs should be ignored.

    "WITH LOCK"

    Access to the record by other programs will be denied.

    "WITH NO LOCK"

    The record will not be locked. This is the default locking option in effect for all statements.

    "WITH KEPT LOCK"

    When single record locking is in-effect, as a new record is accessed, locks held for previous records are released. By using this option, not only is the newly-accessed record locked (as WITH LOCK would do), but prior record locks will be retained as well. A subsequent "READ" without the "KEPT LOCK" option will release all "kept" locks, as will the "UNLOCK" statement.

    "WITH WAIT"

    This option informs GnuCOBOL that the program is willing to wait for a lock held (by another program) on the record being read to be released.

    Without this option, an attempt to read a locked record will be immediately aborted and a file status of 51 will be returned.

    With this option, the program will wait for a pre-configured time for the lock to be released. If the lock is released within the preconfigured wait time, the read will be successful. If the pre-configured wait time expires before the lock is released, the read attempt will be aborted and a 51 file status will be issued.



6.14. Common Clauses on Executable Statements



6.14.1. AT END + NOT AT END

AT END Syntax
=======================================================================

 [ AT END imperative-statement-1 ]
      ~~~
 [ NOT AT END imperative-statement-2 ]
   ~~~    ~~~

=======================================================================
  1. The following points pertain to the use of these clauses on "READ" (see READ) and "RETURN" (see RETURN) statements:
    1. The "AT END" clause will — if present — cause <imperative-statement-1> (see Imperative Statement) to be executed if the statement fails due to a file status of 10 (end-of-file). See File Status Codes, for a list of possible File Status codes.

      An "AT END" clause will not detect other non-zero file-status values.

      Use a "DECLARATIVES" (see DECLARATIVES) routine or an explicitly-declared file status field tested after the "READ" or "RETURN" to detect error conditions other than end-of-file.

    2. A "NOT AT END" clause will cause <imperative-statement-2> to be executed if the "READ" or "RETURN" attempt is successful.
  2. The following points pertain to the use of these clauses on "SEARCH" (see SEARCH) and "SEARCH ALL" (see SEARCH ALL) statements:
    1. An "AT END" clause detects and handles the case where either form of table search has failed to locate an entry that satisfies the search conditions being used.
    2. The "NOT AT END" clause is not allowed on either form of table search.


6.14.2. CORRESPONDING

ADD CORRESPONDING group-item-1 TO group-item-2
MOVE CORRESPONDING group-item-1 TO group-item-2
SUBTRACT CORRESPONDING group-item-1 FROM group-item-2

This option allows one or more data items within one group item (<group-item-1> — the first named on the statement) to be paired with correspondingly-named (hence the name) in a second group item (<group-item-2> — the second named on the statement). The contents of <group-item-1> will remain unaffected by the statement while one or more data items within <group-item-2> will be changed.

In order for <data-item-1>, defined subordinate to group item <group-item-1> to be a "corresponding" match to <data-item-2> which is subordinate to <group-item-2>, each of the following must be true:

  1. Both <data-item-1> and <data-item-2> must have the same name, and that name may not explicitly or implicitly be "FILLER".
  2. Both <data-item-1> and <data-item-2>…
    1. …must exist at the same relative structural "depth" of definition within <group-item-1> and <group-item-2>, respectively
    2. …and all "parent" data items defined within each group item must have identical (but non-"FILLER") names.
  3. When used with a "MOVE" verb…
    1. …one of <data-item-1> or <data-item-2> (but not both) is allowed to be a group item
    2. …and it must be valid to move <data-item-1> TO <data-item-2>.
  4. When used with "ADD" or "SUBTRACT" verbs, both <data-item-1> and <data-item-2> must be numeric, elementary, unedited items.
  5. Neither <data-item-1> nor <data-item-2> may be a "REDEFINES" (see REDEFINES) or "RENAMES" (see RENAMES) of another data item.
  6. Neither <data-item-1> nor <data-item-2> may have an "OCCURS" (see OCCURS) clause, although either may contain subordinate data items that do have an "OCCURS" clause (assuming rule 3a applies)

Observe the definitions of data items "Q" and "Y"…

01  Q.                           01  Y.
    03 X.                            02 A         PIC X(1).
       05 A         PIC 9(1).        02 G1.
       05 G1.                           03 G2.
          10 G2.                           04 B   PIC X(1).
             15 B   PIC X(1).        02 C         PIC X(1).
       05 C.                         02 G3.
          10 FILLER PIC X(1).           03 G5.
       05 G3.                              04 D   PIC X(1).
          10 G4.                        03 G6     PIC X(1).
             15 D   PIC X(1).        02 E         PIC 9(1).
       05 E         PIC X(1).        02 F         PIC X(1).
       05 F         REDEFINES V1     02 G         PIC X(4).
                    PIC X(1).        02 H         OCCURS 4 TIMES
       05 G.                                      PIC X(1).
          10 G6     OCCURS 4 TIMES   66 I         RENAMES E.
                    PIC X(1).        02 J.
       05 H         PIC X(4).           03 K.
       05 I         PIC 9(1).              04 L.
       05 J.                                  05 M.
          10 K.
             15 M   PIC X(1).

The following are the valid CORRESPONDING matches, assuming the statement "MOVE CORRESPONDING X TO Y" is being executed (there are no valid corresponding matches for "ADD CORRESPONDING" or "SUBTRACT CORRESPONDING" because every potential match up violates rule #4):

A, B, C, G

The following are the CORRESPONDING match ups that passed rule #1 (but failed on another rule), and the reasons why they failed.

Data ItemFailure Reason
"D"Fails due to rule #2b
"E"Fails due to rule #3b
"F"Fails due to rule #5
"G1"Fails due to rule #3a
"G2"Fails due to rule #3a
"G3"Fails due to rule #3a
"G4"Fails due to rule #1
"G5"Fails due to rule #1
"G6"Fails due to rule #6
"H"Fails due to rule #6
"I"Fails due to rule #5
"J"Fails due to rule #3a
"K"Fails due to rule #3a
"L"Fails due to rule #1
"M"Fails due to rule #2a


6.14.3. INVALID KEY + NOT INVALID KEY

INVALID KEY Syntax
=======================================================================

 [ INVALID KEY imperative-statement-1 ]
   ~~~~~~~
 [ NOT INVALID KEY imperative-statement-2 ]
   ~~~ ~~~~~~~

=======================================================================

Specification of an "INVALID KEY" clause will allow your program to trap an I/O failure condition (with an I/O error code in the file’s "FILE-STATUS" (see SELECT) field) that has occurred due to a record-not-found condition and handle it gracefully by executing <imperative-statement-1> (see Imperative Statement).

An optional "NOT INVALID KEY"



6.14.4. ON EXCEPTION + NOT ON EXCEPTION

ON EXCEPTION Syntax
=======================================================================

 [ ON EXCEPTION imperative-statement-1 ]
      ~~~~~~~~~
 [ NOT ON EXCEPTION imperative-statement-2 ]
   ~~~    ~~~~~~~~~

=======================================================================

Specification of an exception clause will allow your program to trap a failure condition that has occurred and handle it gracefully by executing <imperative-statement-1> (see Imperative Statement). If such a condition occurs at runtime without having one of these clauses specified, an error message will be generated (by the GnuCOBOL runtime library) to the SYSERR device (pipe 2). The program may also be terminated, depending upon the type and severity of the error.

An optional "NOT ON EXCEPTION"



6.14.5. ON OVERFLOW + NOT ON OVERFLOW

ON OVERFLOW Syntax
=======================================================================

 [ ON OVERFLOW imperative-statement-1 ]
      ~~~~~~~~
 [ NOT ON OVERFLOW imperative-statement-2 ]
   ~~~    ~~~~~~~~

=======================================================================

An "ON OVERFLOW" clause will allow your program to trap a failure condition that has occurred and handle it gracefully by executing <imperative-statement-1> (see Imperative Statement). If such a condition occurs at runtime without having one of these clauses specified, an error message will be generated (by the GnuCOBOL runtime library) to the SYSERR device (pipe 2). The program may also be terminated, depending upon the type and severity of the error.

An optional "NOT ON OVERFLOW"



6.14.6. ON SIZE ERROR + NOT ON SIZE ERROR

ON SIZE ERROR Syntax
=======================================================================

 [ ON SIZE ERROR imperative-statement-1 ]
      ~~~~ ~~~~~
 [ NOT ON SIZE ERROR imperative-statement-2 ]
   ~~~    ~~~~ ~~~~~

=======================================================================

Including an "ON SIZE ERROR" clause on an arithmetic statement will allow your program to trap a failure of an arithmetic statement (either generating a result too large for the receiving field, or attempting to divide by zero) and handle it gracefully by executing <imperative-statement-1> (see Imperative Statement). Field size overflow conditions occur silently, usually without any runtime messages being generated, even though such events rarely lend themselves to generating correct results. Division by zero errors, when no "ON SIZE ERROR" clause exists, will produce an error message (by the GnuCOBOL runtime library) to the SYSERR device (pipe 2) and will also abort the program.

An optional "NOT ON SIZE ERROR"



6.14.7. ROUNDED

ROUNDED Syntax
=======================================================================

 ROUNDED [ MODE IS { AWAY-FROM-ZERO         }
 ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                   { NEAREST-AWAY-FROM-ZERO }
                   { ~~~~~~~~~~~~~~~~~~~~~~ }
                   { NEAREST-EVEN           }
                   { ~~~~~~~~~~~~           }
                   { NEAREST-TOWARD-ZERO    }
                   { ~~~~~~~~~~~~~~~~~~~    }
                   { PROHIBITED             }
                   { ~~~~~~~~~~             }
                   { TOWARD-GREATER         }
                   { ~~~~~~~~~~~~~~         }
                   { TOWARD-LESSER          }
                   { ~~~~~~~~~~~~~          }
                   { TRUNCATION             }
                     ~~~~~~~~~~

=======================================================================

The following rules apply to the rounding behaviour induced by this clause.

  1. Rounding only applies when the result being saved to a receiving field with a "ROUNDED" clause is a non-integer value.
  2. Absence of a "ROUNDED" clause is the same as specifying "ROUNDED MODE IS TRUNCATION".
  3. Use of a "ROUNDED" clause without a "MODE" specification is the same as specifying "ROUNDED MODE IS NEAREST-AWAY-FROM-ZERO".

The behaviour of the eight different rounding modes is defined in the following table. Note that a "…" indicates the last digit repeats. The examples assume an integer receiving field.

"AWAY-FROM-ZERO"

Rounding is to the nearest value of larger magnitude.

-3.510 ⇒ -4+3.510 ⇒ +4
-3.500 ⇒ -4+3.500 ⇒ +4
-3.499… ⇒ -4+3.499… ⇒ +4
-2.500 ⇒ -3+2.500 ⇒ +3
-2.499… ⇒ -3+2.499… ⇒ +3
"NEAREST-AWAY-FROM-ZERO"

Rounding is to the nearest value (larger or smaller). If two values are equally near, the value with the larger absolute value is selected.

-3.510 ⇒ -4+3.510 ⇒ +4
-3.500 ⇒ -4+3.500 ⇒ +4
-3.499… ⇒ -3+3.499… ⇒ +3
-2.500 ⇒ -3+2.500 ⇒ +3
-2.499… ⇒ -2+2.499… ⇒ +2
"NEAREST-EVEN"

Rounding is to the nearest value (larger or smaller). If two values are equally near, the value whose rightmost digit is even is selected. This mode is sometimes called "Banker’s rounding".

-3.510 ⇒ -4+3.510 ⇒ +4
-3.500 ⇒ -4+3.500 ⇒ +4
-3.499… ⇒ -3+3.499… ⇒ +3
-2.500 ⇒ -2+2.500 ⇒ +2
-2.499… ⇒ -2+2.499… ⇒ +2
"NEAREST-TOWARD-ZERO"

Rounding is to the nearest value (larger or smaller). If two values are equally near, the value with the smaller absolute value is selected.

-3.510 ⇒ -4+3.510 ⇒ +4
-3.500 ⇒ -3+3.500 ⇒ +3
-3.499… ⇒ -3+3.499… ⇒ +3
-2.500 ⇒ -2+2.500 ⇒ +2
-2.499… ⇒ -2+2.499… ⇒ +2
"PROHIBITED"

No rounding is performed. If the value cannot be represented exactly in the desired format, the EC-SIZE-TRUNCATION condition (exception code 1005) is set (and may be retrieved via the "ACCEPT" (see ACCEPT FROM Runtime-Info) statement) and the results of the operation are undefined.

-3.510 ⇒ Undefined+3.510 ⇒ Undefined
-3.500 ⇒ Undefined+3.500 ⇒ Undefined
-3.499… ⇒ Undefined+3.499… ⇒ Undefined
-2.500 ⇒ Undefined+2.500 ⇒ Undefined
-2.499… ⇒ Undefined+2.499… ⇒ Undefined
"TOWARD-GREATER"

Rounding is toward the nearest value whose algebraic value is larger.

-3.510 ⇒ -3+3.510 ⇒ +4
-3.500 ⇒ -3+3.500 ⇒ +4
-3.499… ⇒ -3+3.499… ⇒ +4
-2.500 ⇒ -2+2.500 ⇒ +3
-2.499… ⇒ -2+2.499… ⇒ +3
"TOWARD-LESSER"

Rounding is toward the nearest value whose algebraic value is smaller.

-3.510 ⇒ -4+3.510 ⇒ +3
-3.500 ⇒ -4+3.500 ⇒ +3
-3.499… ⇒ -4+3.499… ⇒ +3
-2.500 ⇒ -3+2.500 ⇒ +2
-2.499… ⇒ -3+2.499… ⇒ +2
"TRUNCATION"

Rounding is to the nearest value whose magnitude is smaller.

-3.510 ⇒ -3+3.510 ⇒ +3
-3.500 ⇒ -3+3.500 ⇒ +3
-3.499… ⇒ -3+3.499… ⇒ +3
-2.500 ⇒ -2+2.500 ⇒ +2
-2.499… ⇒ -2+2.499… ⇒ +2


6.15. Special Registers

"COB-CRT-STATUS"

PIC 9(4) — This is the default data item allocated for use by the "ACCEPT <screen-data-item>" statement (see ACCEPT screen-data-item), if no "CRT STATUS" (see SPECIAL-NAMES) clause was specified..

"DEBUG-ITEM"

Group Item — A group item in which debugging information generated by a "USE FOR DEBUGGING" section in the declaratives area of the procedure division will place information documenting why the "USE FOR DEBUGGING" procedure was invoked. Consult the "DECLARATIVES" (see DECLARATIVES) documentation for information on the structure of this register.

"LINAGE-COUNTER"

BINARY-LONG SIGNED — An occurrence of this register exists for each selected file having a "LINAGE" (see File/Sort-Description) clause. If there are multiple files whose file descriptions have "LINAGE" clauses, any explicit references to this register will require qualification (using "OF file-name"). The value of this register will be the current logical line number within the page body. The value of this register cannot be modified.

"LINE-COUNTER"

BINARY-LONG SIGNED — An occurrence of this register exists for each report defined in the program (via an "RD" (see REPORT SECTION)). If there are multiple reports, any explicit references to this register not made in the report section will require qualification ("OF report-name"). The value of this register will be the current logical line number on the current page. The value of this register cannot be modified.

"NUMBER-OF-CALL-PARAMETERS"

BINARY-LONG SIGNED — This register contains the number of arguments passed to a subroutine — the same value that would be returned by the "C$NARG" built-in system subroutine (see C$NARG). Its value will be zero when referenced in a main program. This register, when referenced from within a user-defined function, returns a value of one (1) if the function has any number of arguments and a zero if it has no arguments.

"PAGE-COUNTER"

BINARY-LONG SIGNED — An occurrence of this register exists for each report having an "RD" (see REPORT SECTION). If there are multiple such reports, any explicit references to this register not made in the report section will require qualification ( "OF report-name"). The value of this register will be the current report page number. The value of this register cannot be modified.

"RETURN-CODE"

BINARY-LONG SIGNED — This register provides a numeric data item into which a subroutine may "MOVE" (see MOVE) a value (which will then be available to the calling program) prior to transferring control back to the program that called it, or into which a main program may "MOVE" a value before returning control to the operating system. Many built-in subroutines will return a value using this register. These values are — by convention — used to signify success (usually with a value of 0) or failure (usually with a non-zero value) of the process the program was attempting to perform. This register may also be modified by a subprogram as a result of that subprogram’s use of the "RETURNING" (see PROCEDURE DIVISION RETURNING) clause.

"SORT-RETURN"

BINARY-LONG SIGNED — This register is used to report the success/fail status of a "RELEASE" (see RELEASE) or "RETURN" (see RETURN) statement. A value of 0 is reported on success. A value of 16 denotes failure. An "AT END" (see AT END + NOT AT END) condition on a "RETURN" is not considered a failure.

"WHEN-COMPILED"

PIC X(16) — This register contains the date and time the program was compiled in the format "mm/dd/yyhh.mm.ss". Note that only a two-digit year is provided.



6.16. Intrinsic Functions

MOVE FUNCTION LENGTH(Employee-Last-Name) TO Employee-LN-Len

Note how the word "FUNCTION" is part of the syntax when you use an intrinsic function. You can use intrinsic functions without having to include the reserved word "FUNCTION" via settings in the "REPOSITORY" (see REPOSITORY) paragraph. You may accomplish the same thing by specifying the "-fintrinsics" switch

User-written functions (see Subprogram Types) never require the "FUNCTION" keyword when they are executed, because each user-written function a program uses must be included in that program’s "REPOSITORY" paragraph, which therefore makes the "FUNCTION" keyword optional.

The following intrinsic functions, known to other "dialects" of COBOL, are defined to GnuCOBOL as reserved words but are not otherwise implemented currently. Any attempts to use these functions will result in a compile-time error message.

BOOLEAN-OF-INTEGER
FORMATTED-CURRENT-DATE
INTEGER-OF-FORMATTED-DATE
CHAR-NATIONAL
FORMATTED-DATE
NATIONAL-OF
DISPLAY-OF
FORMATTED-DATETIME
STANDARD-COMPARE
EXCEPTION-FILE-N
FORMATTED-TIME
TEST-FORMATTED-DATETIME
EXCEPTION-LOCATION-N
INTEGER-OF-BOOLEAN

The supported intrinsic functions are listed in the following sections, along with their syntax and usage notes.



6.16.1. ABS

ABS Function Syntax
=======================================================================

 ABS(number)
 ~~~

=======================================================================


6.16.2. ACOS

ACOS Function Syntax
=======================================================================

 ACOS(cosine)
 ~~~~

=======================================================================

The result will be an angle, expressed in radians. You may convert this to an angle measured in degrees, as follows:

"COMPUTE <degrees> = ( <radians> * 180 ) / FUNCTION PI"


6.16.3. ANNUITY

ANNUITY Function Syntax
=======================================================================

 ANNUITY(interest-rate, number-of-periods)
 ~~~~~~~

=======================================================================

The <interest-rate> is the rate of interest paid at each payment. If you only have an annual interest rate and you wish to compute monthly annuity payments, divide the annual interest rate by 12 and use that value for <interest-rate> on this function.

Multiply the result of this function times the desired principal amount to determine the amount of each period’s payment.

A note for the financially challenged: an annuity is basically a reverse loan; an accountant would take the result of this function multiplied by -1 times the principal amount to compute a loan payment you are making.



6.16.4. ASIN

ASIN Function Syntax
=======================================================================

 ASIN(sine)
 ~~~~

=======================================================================

The result will be an angle, expressed in radians. You may convert this to an angle measured in degrees, as follows:

"COMPUTE <degrees> = ( <radians> * 180 ) / FUNCTION PI"


6.16.5. ATAN

ATAN Function Syntax
=======================================================================

 ATAN(tangent)
 ~~~~

=======================================================================

The result will be an angle, expressed in radians. You may convert this to an angle measured in degrees, as follows:

"COMPUTE <degrees> = ( <radians> * 180 ) / FUNCTION PI"


6.16.6. BYTE-LENGTH

BYTE-LENGTH Function Syntax
=======================================================================

 BYTE-LENGTH(string)
 ~~~~~~~~~~~

=======================================================================

For example, if <string> is encoded using a double-byte character set such as UNICODE (where each character is represented by 16 bits of storage, not the 8-bits inherent to character sets like ASCII or EBCDIC), then calling this function with a <string> argument whose "PICTURE" (see PICTURE) is "X(4)" would return a value of 8 rather than the value 4.

Contrast this with the "LENGTH" (see LENGTH) function.



6.16.7. CHAR

CHAR Function Syntax
=======================================================================

 CHAR(integer)
 ~~~~

=======================================================================

For example, if the program is using the (default) ASCII character set, CHAR(34) returns the 34th character in the ASCII character set — an exclamation-point ("!"). If you are using this function to convert a numeric value to its corresponding ASCII character, you must use an argument value one greater than the numeric value.

If an argument whose value is less than 1 or greater than 256 is specified, the character in the program collating sequence corresponding to a value of all zero bits is returned.

The following code is an alternative approach when you just wish to convert a number to its ASCII equivalent:

01  Char-Value.
    05 Numeric-Value        USAGE BINARY-CHAR.
…
    MOVE numeric-character-value TO Numeric-Value

The "Char-Value" item now has the corresponding ASCII character value.



6.16.8. COMBINED-DATETIME

COMBINED-DATETIME Function Syntax
=======================================================================

 COMBINED-DATETIME(days, seconds)
 ~~~~~~~~~~~~~~~~~

=======================================================================

If a <days> value less than 1 or greater than 3067671 is specified, or if a <seconds> value less than 1 or greater than 86400 is specified, a value of 0 is returned and a runtime error will result.



6.16.9. CONCATENATE

CONCATENATE Function Syntax
=======================================================================

 CONCATENATE(string-1 [, string-2 ]...)
 ~~~~~~~~~~~

=======================================================================

If a numeric literal or "PIC 9" identifier is specified as an argument, decimal points, if any, will be removed and negative signs in "PIC S9" fields or numeric literals will be inserted as defined by the "SIGN IS" (see SIGN IS) clause (or absence thereof) of the field. Numeric literals are processed as if "SIGN IS TRAILING SEPARATE" were in effect.



6.16.10. COS

COS Function Syntax
=======================================================================

 COS(angle)
 ~~~

=======================================================================

The <angle> is assumed to be a value expressed in radians. If you need to determine the cosine of an angle measured in degrees, you first need to convert that angle to radians as follows:

"COMPUTE <radians> = ( <degrees> * FUNCTION PI) / 180"


6.16.11. CURRENCY-SYMBOL

CURRENCY-SYMBOL Function Syntax
=======================================================================

 CURRENCY-SYMBOL
 ~~~~~~~~~~~~~~~

=======================================================================

Changing the currency symbol via the "SPECIAL-NAMES" (see SPECIAL-NAMES) paragraph’s "CURRENCY SYMBOL" setting will not affect the value returned by this function.



6.16.12. CURRENT-DATE

CURRENT-DATE Function Syntax
=======================================================================

 CURRENT-DATE
 ~~~~~~~~~~~~

=======================================================================
01  CURRENT-DATE-AND-TIME.
    05 CDT-Year                PIC 9(4).
    05 CDT-Month               PIC 9(2). *> 01-12
    05 CDT-Day                 PIC 9(2). *> 01-31
    05 CDT-Hour                PIC 9(2). *> 00-23
    05 CDT-Minutes             PIC 9(2). *> 00-59
    05 CDT-Seconds             PIC 9(2). *> 00-59
    05 CDT-Hundredths-Of-Secs  PIC 9(2). *> 00-99
    05 CDT-GMT-Diff-Hours      PIC S9(2)
                               SIGN LEADING SEPARATE.
    05 CDT-GMT-Diff-Minutes    PIC 9(2). *> 00 or 30

Since this function has no arguments, no parenthesis should be specified.



6.16.13. DATE-OF-INTEGER

DATE-OF-INTEGER Function Syntax
=======================================================================

 DATE-OF-INTEGER(integer)
 ~~~~~~~~~~~~~~~

=======================================================================

A value less than 1 or greater than 3067671 (9999/12/31) will return a result of 0.



6.16.14. DATE-TO-YYYYMMDD

DATE-TO-YYYYMMDD Function Syntax
=======================================================================

 DATE-TO-YYYYMMDD(yymmdd [, yy-cutoff ])
 ~~~~~~~~~~~~~~~~

=======================================================================

The optional <yy-cutoff> (a numeric integer data item or literal) argument is the year cutoff used to delineate centuries; if the year component of the date meets or exceeds this cutoff value, the result will be 19yymmdd; if the year component of the date is less than the cutoff value, the result will be 20yymmdd. The default cutoff value if no second argument is given will be 50.



6.16.15. DAY-OF-INTEGER

DAY-OF-INTEGER Function Syntax
=======================================================================

 DAY-OF-INTEGER(integer)
 ~~~~~~~~~~~~~~

=======================================================================

A value less than 1 or greater than 3067671 (9999/12/31) will return a result of 0.



6.16.16. DAY-TO-YYYYDDD

DAY-TO-YYYYDDD Function Syntax
=======================================================================

 DAY-TO-YYYYDDD(yyddd [, yy-cutoff])
 ~~~~~~~~~~~~~~

=======================================================================

The optional <yy-cutoff> argument (a numeric integer data item or literal) is the year cutoff used to delineate centuries; if the year component of the date meets or exceeds this cutoff value, the result will be 19yyddd; if the year component of the date is less than the cutoff, the result will be 20yyddd. The default cutoff value if no second argument is given will be 50.



6.16.17. E

E Function Syntax
=======================================================================

 E
 ~

=======================================================================

Since this function has no arguments, no parenthesis should be specified.



6.16.18. EXCEPTION-FILE

EXCEPTION-FILE Function Syntax
=======================================================================

 EXCEPTION-FILE
 ~~~~~~~~~~~~~~

=======================================================================

The name returned after the file status information will be returned only if the returned file status value is not 00.

Since this function has no arguments, no parenthesis should be specified.

The documentation of the "CBL_ERROR_PROC" built-in system subroutine (see CBL_ERROR_PROC) built-in subroutine illustrates the use of this function.



6.16.19. EXCEPTION-LOCATION

EXCEPTION-LOCATION Function Syntax
=======================================================================

 EXCEPTION-LOCATION
 ~~~~~~~~~~~~~~~~~~

=======================================================================

Since this function has no arguments, no parenthesis should be specified.

The program must be compiled with the "-debug" switch

The documentation of the "CBL_ERROR_PROC" built-in system subroutine (see CBL_ERROR_PROC) built-in subroutine illustrates the use of this function.



6.16.20. EXCEPTION-STATEMENT

EXCEPTION-STATEMENT Function Syntax
=======================================================================

 EXCEPTION-STATEMENT
 ~~~~~~~~~~~~~~~~~~~

=======================================================================

Since this function has no arguments, no parenthesis should be specified.

The program must be compiled with the "-debug" switch

The documentation of the "CBL_ERROR_PROC" built-in system subroutine (see CBL_ERROR_PROC) built-in subroutine illustrates the use of this function.



6.16.21. EXCEPTION-STATUS

EXCEPTION-STATUS Function Syntax
=======================================================================

 EXCEPTION-STATUS
 ~~~~~~~~~~~~~~~~

=======================================================================

Since this function has no arguments, no parenthesis should be specified.

The documentation of the "CBL_ERROR_PROC" built-in system subroutine (see CBL_ERROR_PROC) built-in subroutine illustrates the use of this function.

The following are the error type strings, and their corresponding exception codes and descriptions.

CodeError TypeDescription
0101EC-ARGUMENT-FUNCTIONFunction argument error
0202EC-BOUND-ODOOCCURS … DEPENDING ON data item out of bounds
0204EC-BOUND-PTRData-pointer contains an address that is out of bounds
0205EC-BOUND-REF-MODReference modifier out of bounds
0207EC-BOUND-SUBSCRIPTSubscript out of bounds
0303EC-DATA-INCOMPATIBLEIncompatible data exception
0500EC-I-Oinput-output exception
0501EC-I-O-AT-ENDI-O status "1x"
0502EC-I-O-EOPAn end of page condition occurred
0504EC-I-O-FILE-SHARINGI-O status "6x"
0505EC-I-O-IMPI-O status "9x"
0506EC-I-O-INVALID-KEYI-O status "2x"
0508EC-I-O-LOGIC-ERRORI-O status "4x"
0509EC-I-O-PERMANENT-ERRORI-O status "3x"
050AEC-I-O-RECORD-OPERATIONI-O status "5x"
0601EC-IMP-ACCEPTImplementation-defined accept condition
0602EC-IMP-DISPLAYImplementation-defined display condition
0A00EC-OVERFLOWOverflow condition
0A02EC-OVERFLOW-STRINGSTRING overflow condition
0A03EC-OVERFLOW-UNSTRINGUNSTRING overflow condition
0B05EC-PROGRAM-NOT-FOUNDCalled program not found
0D03EC-RANGE-INSPECT-SIZESize of replace item in inspect differs
1000EC-SIZESize error exception
1004EC-SIZE-OVERFLOWArithmetic overflow in calculation
1005EC-SIZE-TRUNCATIONSignificant digits truncated in store
1007EC-SIZE-ZERO-DIVIDEDivision by zero
1202EC-STORAGE-NOT-ALLOCThe data-pointer specified in a FREE statement does not identify currently allocated storage
1203EC-STORAGE-NOT-AVAILThe amount of storage requested by an ALLOCATE statement is not available


6.16.22. EXP

EXP Function Syntax
=======================================================================

 EXP(number)
 ~~~

=======================================================================


6.16.23. EXP10

EXP10 Function Syntax
=======================================================================

 EXP10(number)
 ~~~~~

=======================================================================


6.16.24. FACTORIAL

FACTORIAL Function Syntax
=======================================================================

 FACTORIAL(number)
 ~~~~~~~~~

=======================================================================


6.16.25. FRACTION-PART

FRACTION-PART Function Syntax
=======================================================================

 FRACTION-PART(number)
 ~~~~~~~~~~~~~

=======================================================================
<number> -- FUNCTION INTEGER-PART(<number>)


6.16.26. HIGHEST-ALGEBRAIC

HIGHEST-ALGEBRAIC Function Syntax
=======================================================================

 HIGHEST-ALGEBRAIC(numeric-identifier)
 ~~~~~~~~~~~~~~~~~

=======================================================================


6.16.27. INTEGER

INTEGER Function Syntax
=======================================================================

 INTEGER(number)
 ~~~~~~~

=======================================================================


6.16.28. INTEGER-OF-DATE

INTEGER-OF-DATE Function Syntax
=======================================================================

 INTEGER-OF-DATE(date)
 ~~~~~~~~~~~~~~~

=======================================================================

Once in that form, mathematical operations may be performed against the internal date before it is transformed back into a date using the "DATE-OF-INTEGER" (see DATE-OF-INTEGER) or "DAY-OF-INTEGER" (see DAY-OF-INTEGER) function.



6.16.29. INTEGER-OF-DAY

INTEGER-OF-DAY Function Syntax
=======================================================================

 INTEGER-OF-DAY(date)
 ~~~~~~~~~~~~~~

=======================================================================

Once in that form, mathematical operations may be performed against the internal date before it is transformed back into a date using the "DATE-OF-INTEGER" (see DATE-OF-INTEGER) or "DAY-OF-INTEGER" (see DAY-OF-INTEGER) function.



6.16.30. INTEGER-PART

INTEGER-PART Function Syntax
=======================================================================

 INTEGER-PART(number)
 ~~~~~~~~~~~~

=======================================================================


6.16.31. LENGTH

LENGTH Function Syntax
=======================================================================

 LENGTH(string)
 ~~~~~~

=======================================================================

The value returned by this function is not the number of bytes of storage occupied by string, but rather the number of actual characters making up the string. For example, if <string> is encoded using a double-byte character set such as UNICODE (where each character is represented by 16 bits of storage, not the 8-bits inherent to character sets like ASCII or EBCDIC), then calling this function with a <string> argument whose "PICTURE is X(4)" would return a value of 4 rather than the value 8 (the actual number of bytes of storage occupied by that item).

Contrast this function with the "BYTE-LENGTH" (see BYTE-LENGTH) and "LENGTH-AN" (see LENGTH-AN) functions.



6.16.32. LENGTH-AN

LENGTH-AN Function Syntax
=======================================================================

 LENGTH-AN(string)
 ~~~~~~~~~

=======================================================================

This intrinsic function is identical to the "BYTE-LENGTH" (see BYTE-LENGTH) function.

Note that the value returned by this function is not the number of characters making up the <string>, but rather the number of actual bytes of storage required to store <string>. For example, if <string> is encoded using a double-byte character set such as UNICODE (where each character is represented by 16 bits of storage, not the 8-bits inherent to character sets like ASCII or EBCDIC), then calling this function with a <string> argument whose "PICTURE is X(4)" would return a value of 8 rather than the value 4.

Contrast this with the "LENGTH" (see LENGTH) function.



6.16.33. LOCALE-COMPARE

LOCALE-COMPARE Function Syntax
=======================================================================

 LOCALE-COMPARE(argument-1, argument-2 [ , locale ])
 ~~~~~~~~~~~~~~

=======================================================================

Either or both of the 1st two arguments may be an alphanumeric literal, a group item or an elementary item appropriate to storing alphabetic or alphanumeric data. If the lengths of the two arguments are unequal, the shorter will be assumed to be padded to the right with spaces.

The two arguments will be compared, character by character, against each other until their relationship to each other can be determined. The comparison is made according to the cultural rules in effect for the specified <locale> name or for the current locale if no <locale> argument is specified. Once that relationship is determined, a one-character alphanumeric value will be returned as follows:

See LOCALE Names, for a list of typically-available locale names.



6.16.34. LOCALE-DATE

LOCALE-DATE Function Syntax
=======================================================================

 LOCALE-DATE(date [, locale ])
 ~~~~~~~~~~~

=======================================================================

You may include an optional second argument to specify the <locale> name (group item or "PIC X" identifier) you’d like to use for date formatting. If used, this second argument must be an identifier. Locale names are specified using UNIX-standard names.



6.16.35. LOCALE-TIME

LOCALE-TIME Function Syntax
=======================================================================

 LOCALE-TIME(time [, locale ])
 ~~~~~~~~~~~

=======================================================================

You may include an optional <locale> name (a group item or "PIC X" identifier) you’d like to use for time formatting. If used, this second argument must be an identifier. Locale names are specified using UNIX-standard names.



6.16.36. LOCALE-TIME-FROM-SECONDS

LOCALE-TIME-FROM-SECONDS Function Syntax
=======================================================================

 LOCALE-TIME-FROM-SECONDS(seconds [, locale ])
 ~~~~~~~~~~~~~~~~~~~~~~~~

=======================================================================

You may include an optional <locale> name (a group item or "PIC X" identifier) you’d like to use for time formatting. If used, this second argument must be an identifier. Locale names are specified using UNIX-standard names.

See LOCALE Names, for a list of typically-available locale names.



6.16.37. LOG

LOG Function Syntax
=======================================================================

 LOG(number)
 ~~~

=======================================================================


6.16.38. LOG10

LOG10 Function Syntax
=======================================================================

 LOG10(number)
 ~~~~~

=======================================================================


6.16.39. LOWER-CASE

LOWER-CASE Function Syntax
=======================================================================

 LOWER-CASE(string)
 ~~~~~~~~~~

=======================================================================

What constitutes a "letter" (or upper/lower case too, for that manner) may be influenced through the use of a "CHARACTER CLASSIFICATION" (see OBJECT-COMPUTER).



6.16.40. LOWEST-ALGEBRAIC

LOWEST-ALGEBRAIC Function Syntax
=======================================================================

 LOWEST-ALGEBRAIC(numeric-identifier)
 ~~~~~~~~~~~~~~~~

=======================================================================


6.16.41. MAX

MAX Function Syntax
=======================================================================

 MAX(number-1 [, number-2 ]...)
 ~~~

=======================================================================


6.16.42. MEAN

MEAN Function Syntax
=======================================================================

 MEAN(number-1 [, number-2 ]...)
 ~~~~

=======================================================================


6.16.43. MEDIAN

MEDIAN Function Syntax
=======================================================================

 MEDIAN(number-1 [, number-2 ]...)
 ~~~~~~

=======================================================================


6.16.44. MIDRANGE

MIDRANGE Function Syntax
=======================================================================

 MIDRANGE(number-1 [, number-2 ]...)
 ~~~~~~~~

=======================================================================


6.16.45. MIN

MIN Function Syntax
=======================================================================

 MIN(number-1 [, number-2 ]...)
 ~~~

=======================================================================


6.16.46. MOD

MOD Function Syntax
=======================================================================

 MOD(value, modulus)
 ~~~

=======================================================================


6.16.47. MODULE-CALLER-ID

MODULE-CALLER-ID Function Syntax
=======================================================================

 MODULE-CALLER-ID
 ~~~~~~~~~~~~~~~~

=======================================================================

The discussion of the "MODULE-TIME" (see MODULE-TIME) function includes a sample program that uses this function.

Since this function has no arguments, no parenthesis should be specified.



6.16.48. MODULE-DATE

MODULE-DATE Function Syntax
=======================================================================

 MODULE-DATE
 ~~~~~~~~~~~

=======================================================================

The discussion of the "MODULE-TIME" (see MODULE-TIME) function includes a sample program that uses this function.

Since this function has no arguments, no parenthesis should be specified.



6.16.49. MODULE-FORMATTED-DATE

MODULE-FORMATTED-DATE Function Syntax
=======================================================================

 MODULE-FORMATTED-DATE
 ~~~~~~~~~~~~~~~~~~~~~

=======================================================================

The discussion of the "MODULE-TIME" (see MODULE-TIME) function includes a sample program that uses this function.

Since this function has no arguments, no parenthesis should be specified.



6.16.50. MODULE-ID

MODULE-ID Function Syntax
=======================================================================

 MODULE-ID
 ~~~~~~~~~

=======================================================================

The discussion of the "MODULE-TIME" (see MODULE-TIME) function includes a sample program that uses this function.

Since this function has no arguments, no parenthesis should be specified.



6.16.55. MODULE-PATH

MODULE-PATH Function Syntax
=======================================================================

 MODULE-PATH
 ~~~~~~~~~~~

=======================================================================

The discussion of the "MODULE-TIME" (see MODULE-TIME) function includes a sample program that uses this function.

Since this function has no arguments, no parenthesis should be specified.



6.16.52. MODULE-SOURCE

MODULE-SOURCE Function Syntax
=======================================================================

 MODULE-SOURCE
 ~~~~~~~~~~~~~

=======================================================================

The discussion of the "MODULE-TIME" (see MODULE-TIME) function includes a sample program that uses this function.

Since this function has no arguments, no parenthesis should be specified.



6.16.53. MODULE-TIME

MODULE-TIME Function Syntax
=======================================================================

 MODULE-TIME
 ~~~~~~~~~~~

=======================================================================

Since this function has no arguments, no parenthesis should be specified.

The following sample program uses all the MODULE- Functions:

IDENTIFICATION DIVISION.
PROGRAM-ID. DEMOMODULE.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
    FUNCTION ALL INTRINSIC.
PROCEDURE DIVISION.
000-Main.
    DISPLAY "MODULE-CALLER-ID      = [" MODULE-CALLER-ID "]"
    DISPLAY "MODULE-DATE           = [" MODULE-DATE "]"
    DISPLAY "MODULE-FORMATTED-DATE = [" MODULE-FORMATTED-DATE "]"
    DISPLAY "MODULE-ID             = [" MODULE-ID "]"
    DISPLAY "MODULE-PATH           = [" MODULE-PATH "]"
    DISPLAY "MODULE-SOURCE         = [" MODULE-SOURCE "]"
    DISPLAY "MODULE-TIME           = [" MODULE-TIME "]"
    STOP RUN
    .

The program produces this output when executed:

MODULE-CALLER-ID      = []
MODULE-DATE           = [20120614]
MODULE-FORMATTED-DATE = [Jun 14 2012 15:07:45]
MODULE-ID             = [DEMOMODULE]
MODULE-PATH           = [E:\Programs\Demos\DEMOMODULE.exe]
MODULE-SOURCE         = [DEMOMODULE.cbl]
MODULE-TIME           = [150745]


6.16.54. MONETARY-DECIMAL-POINT

MONETARY-DECIMAL-POINT Function Syntax
=======================================================================

 MONETARY-DECIMAL-POINT
 ~~~~~~~~~~~~~~~~~~~~~~

=======================================================================

On UNIX (including OSX, Windows/Cygwin and Windows/MinGW) systems, your locale is established via the

Using the "DECIMAL-POINT IS COMMA" (see SPECIAL-NAMES) clause in your program will not affect the value returned by this function.

Since this function has no arguments, no parenthesis should be specified.



6.16.55. MONETARY-THOUSANDS-SEPARATOR

MONETARY-THOUSANDS-SEPARATOR Function Syntax
=======================================================================

 MONETARY-THOUSANDS-SEPARATOR
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

=======================================================================

On UNIX (including OSX, Windows/Cygwin and Windows/MinGW) systems, your locale is established via the

Using the "DECIMAL-POINT IS COMMA" (see SPECIAL-NAMES) clause in your program will not affect the value returned by this function.

Since this function has no arguments, no parenthesis should be specified.



6.16.56. NUMERIC-DECIMAL-POINT

NUMERIC-DECIMAL-POINT Function Syntax
=======================================================================

 NUMERIC-DECIMAL-POINT
 ~~~~~~~~~~~~~~~~~~~~~

=======================================================================

On UNIX (including OSX, Windows/Cygwin and Windows/MinGW) systems, your locale is established via the

Using the "DECIMAL-POINT IS COMMA" (see SPECIAL-NAMES) clause in your program will not affect the value returned by this function.

Since this function has no arguments, no parenthesis should be specified.



6.16.57. NUMERIC-THOUSANDS-SEPARATOR

NUMERIC-THOUSANDS-SEPARATOR Function Syntax
=======================================================================

 NUMERIC-THOUSANDS-SEPARATOR
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~

=======================================================================

On UNIX (including OSX, Windows/Cygwin and Windows/MinGW) systems, your locale is established via the

Using the "DECIMAL-POINT IS COMMA" (see SPECIAL-NAMES) clause in your program will not affect the value returned by this function.

Since this function has no arguments, no parenthesis should be specified.



6.16.58. NUMVAL

NUMVAL Function Syntax
=======================================================================

 NUMVAL(string)
 ~~~~~~

=======================================================================

The <string> must have any of the following formats, where ’#’ represents a sequence of one or more decimal digits:

#   -#   +#   #-   #+   #CR   #DB   #CR
#.#   -#.#   +#.#   #.#-   #.#+   #.#CR   #.#DB

There must be at least one digit character in the string.

Leading and/or trailing spaces are allowed, as are spaces before and/or after the sign, CR and DB characters.



6.16.59. NUMVAL-C

NUMVAL-C Function Syntax
=======================================================================

 NUMVAL-C(string[,symbol])
 ~~~~~~~~

=======================================================================

The optional <symbol> character represents the currency symbol (a single-character group item, "USAGE DISPLAY" elementary item or alphanumeric literal) that may be used as the currency character in <string>. If no <symbol> is specified, the value that would be returned by the "CURRENCY-SYMBOL" intrinsic function (see CURRENCY-SYMBOL) will be used.

<string> may have any of the following formats, where ’#’ represents a sequence of one or more decimal digits and ’$’ represents the <symbol> character:

#   -#   +#   #-   #+   #CR   #DB   #CR
#.#   -#.#   +#.#   #.#-   #.#+   #.#CR   #.#DB
$#   -$#   +$#   $#-   $#+   $#CR   $#DB   $#CR
$#.#   -$#.#   +$#.#   $#.#-   $#.#+   $#.#CR   $#.#DB

There must be at least one digit character in the string.

Leading and/or trailing spaces are allowed, as are spaces before and/or after the currency symbol, sign, CR and DB characters.



6.16.60. NUMVAL-F

NUMVAL-F Function Syntax
=======================================================================

 NUMVAL-F(char)
 ~~~~~~~~

=======================================================================
#   -#   +#   #E#   -#E#   +#E#
#E+#   -#E+#   +#E+#   #E-#   -#E-#   +#E-#
#.#   -#.#   +#.#   #.#E#   -#.#E#   +#.#E#
#.#E+#   -#.#E+#   +#.#E+#   #.#E-#   -#.#E-#   +#.#E-#

There must be at least one digit character both before and after the "E" in the string.

Leading and/or trailing spaces are allowed, as are spaces before and/or after any sign characters.



6.16.61. ORD

ORD Function Syntax
=======================================================================

 ORD(char)
 ~~~

=======================================================================

For example, assuming the program is using the standard ASCII collating sequence, "ORD('!')" returns 34 because "!" is the 34th ASCII character. If you are using this function to convert an ASCII character to its numeric value, you must subtract one from the result.

The following code is an alternative approach when you just wish to convert an ASCII character to its numeric equivalent:

01  Char-Value.
    05 Numeric-Value        USAGE BINARY-CHAR.
…
    MOVE "character" TO Char-Value

"Numeric-Value" now has the numeric value of "character".



6.16.62. ORD-MAX

ORD-MAX Function Syntax
=======================================================================

 ORD-MAX(char-1 [, char-2 ]...)
 ~~~~~~~

=======================================================================

For example, assuming the program is using the standard ASCII collating sequence, "ORD-MAX('Z', 'z', '!')" returns 2 because the 2nd character in the argument list (the ASCII character ’z’) occurs after ’Z’ and ’!’ in the program collating sequence. Each <char-n> argument may be a group item, "USAGE DISPLAY" elementary item or alphanumeric literal.



6.16.63. ORD-MIN

ORD-MIN Function Syntax
=======================================================================

 ORD-MIN(char-1 [, char-2 ]...)
 ~~~~~~~

=======================================================================

For example, assuming the program is using the standard ASCII collating sequence, "ORD-MIN('Z', 'z', '!')" returns 3 because the 3rd character in the argument list (the ASCII character ’!’) occurs before ’Z’ and ’z’ in the program collating sequence. Each <char-n> argument may be a group item, "USAGE DISPLAY" elementary item or alphanumeric literal.



6.16.64. PI

PI Function Syntax
=======================================================================

 PI
 ~~

=======================================================================

Since this function has no arguments, no parenthesis should be specified.



6.16.65. PRESENT-VALUE

PRESENT-VALUE Function Syntax
=======================================================================

 PRESENT-VALUE(rate, value-1 [, value-2 ])
 ~~~~~~~~~~~~~

=======================================================================

All arguments are numeric data items and/or numeric literals.



6.16.66. RANDOM

RANDOM Function Syntax
=======================================================================

 RANDOM[(seed)]
 ~~~~~~

=======================================================================

The purpose of the optional <seed> argument, is to initialize the chain of pseudo-random numbers that will be returned by the function. Not only will calls to this function using the same <seed> value return the same pseudo-random number, but so will all subsequent executions of the function without a <seed>. This is actually a good thing when you are testing your program because you can rely on always receiving the same sequence of "random" numbers if you always start using the same <seed>.

The <seed> may be any form of literal or data item. If <seed> is numeric, its numeric value will serve as the seed value. If <seed> is alphanumeric, a value for it will be determined as if it were used as an argument to "NUMVAL" (see NUMVAL).

Take, for example, the following sample program:

    IDENTIFICATION DIVISION.
    PROGRAM-ID. DEMORANDOM.
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    01  Pseudo-Random-Number        USAGE COMP-1.
    PROCEDURE DIVISION.
    000-Main.
        MOVE FUNCTION RANDOM(1) TO Pseudo-Random-Number
        DISPLAY Pseudo-Random-Number
        PERFORM 4 TIMES
            MOVE FUNCTION RANDOM    TO Pseudo-Random-Number
            DISPLAY Pseudo-Random-Number
        END-PERFORM
        STOP RUN
        .

Every time this program is executed, it will produce the same output, because the same sequence of pseudo-random numbers will be generated:

    0.41
    0.18467
    0.63340002
    0.26499999
    0.19169

It is worth mentioning that if the first execution of "RANDOM" in your program lacks a <seed> argument, the result will be exactly as if that execution were coded with a <seed> argument value of 1.

Once your program has been thoroughly tested, you’ll want different sequences to be generated each time the program runs. One possible way to accomplish this is to use a <seed> that is likely to be different every time the program is executed, as is likely to be the case if the first "MOVE" statement in the previous example were replaced by this:

    MOVE RANDOM(FUNCTION CURRENT-DATE(1:16))
      TO Pseudo-Random-Number

The first 16 characters returned by the "CURRENT-DATE" (see CURRENT-DATE) function will be a number in the format "YYYYMMDDhhmmssnn", where "YYYYMMDD" is the current calendar date and "hhmmssnn" is the current time of day to the one one-hundredth of a second. Since two different executions of the program will never get identical "CURRENT-DATE" values (unless they are executed in extremely close time frames to one another), using those first sixteen characters as the "RANDOM" seed will guarantee that receiving a duplicate sequence of pseudo-random numbers in two different executions of the program will be HIGHLY unlikely.



6.16.67. RANGE

RANGE Function Syntax
=======================================================================

 RANGE(number-1 [, number-2 ]...)
 ~~~~~

=======================================================================

All <number-n> arguments are numeric data items and/or numeric literals.



6.16.68. REM

REM Function Syntax
=======================================================================

 REM(number,divisor)
 ~~~

=======================================================================


6.16.69. REVERSE

REVERSE Function Syntax
=======================================================================

 REVERSE(string)
 ~~~~~~~

=======================================================================


6.16.70. SECONDS-FROM-FORMATTED-TIME

SECONDS-FROM-FORMATTED-TIME Function Syntax
=======================================================================

 SECONDS-FROM-FORMATTED-TIME(format,time)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~

=======================================================================

The <time> string must contain hours, minutes and seconds. The time argument may be specified as a group item, "USAGE DISPLAY" elementary item or an alphanumeric literal.

The <format> argument is a string (a group item, "USAGE DISPLAY" elementary item or an alphanumeric literal) documenting the format of <time> using "hh", "mm" and "ss" to denote where the respective time information can be found. Any other characters found in <format> represent character positions that will be ignored. For example, a format of "hhmmss" indicates that <time> will be treated as a six-digit string value where the first two characters are the number of hours, the next two represent minutes and the last two represent seconds. A <format> of "hh:mm:ss", however, describes <time> as an eight-character string where characters 3 and 6 will be ignored.



6.16.71. SECONDS-PAST-MIDNIGHT

SECONDS-PAST-MIDNIGHT Function Syntax
=======================================================================

 SECONDS-PAST-MIDNIGHT
 ~~~~~~~~~~~~~~~~~~~~~

=======================================================================

Since this function has no arguments, no parenthesis should be specified.



6.16.72. SIGN

SIGN Function Syntax
=======================================================================

 SIGN(number)
 ~~~~

=======================================================================


6.16.73. SIN

SIN Function Syntax
=======================================================================

 SIN(angle)
 ~~~

=======================================================================

The <angle> is assumed to be a value expressed in radians. If you need to determine the sine of an angle measured in degrees, you first need to convert that angle to radians as follows:

"COMPUTE <radians> = ( <degrees> * FUNCTION PI) / 180"


6.16.74. SQRT

SQRT Function Syntax
=======================================================================

 SQRT(number)
 ~~~~

=======================================================================

The following two statements produce identical results:

01  Result           PIC 9(4).9(10).
…
    MOVE FUNCTION SQRT(15) TO Result
    COMPUTE Result = 15 ^ 0.5


6.16.75. STANDARD-DEVIATION

STANDARD-DEVIATION Function Syntax
=======================================================================

 STANDARD-DEVIATION(number-1 [, number-2 ]...)
 ~~~~~~~~~~~~~~~~~~

=======================================================================


6.16.76. STORED-CHAR-LENGTH

STORED-CHAR-LENGTH Function Syntax
=======================================================================

 STORED-CHAR-LENGTH(string)
 ~~~~~~~~~~~~~~~~~~

=======================================================================


6.16.77. SUBSTITUTE

SUBSTITUTE Function Syntax
=======================================================================

 SUBSTITUTE(string, from-1, to-1 [, from-n, to-n ]...)
 ~~~~~~~~~~

=======================================================================

The <from-n> strings must match sequences in <string> exactly with regard to value and case.

A <from-n> string does not have to be the same length as its corresponding <to-n> string.

All arguments are group items, <USAGE DISPLAY> elementary items or alphanumeric literals.

A null <to-n> string will be treated as a single space.



6.16.78. SUBSTITUTE-CASE

SUBSTITUTE-CASE Function Syntax
=======================================================================

 SUBSTITUTE-CASE(string, from-1, to-1 [, from-n, to-n ]...)
 ~~~~~~~~~~~~~~~

=======================================================================

All arguments are group items, "USAGE DISPLAY" elementary items or alphanumeric literals.



6.16.79. SUM

SUM Function Syntax
=======================================================================

 SUM(number-1 [, number-2 ]...)
 ~~~

=======================================================================


6.16.80. TAN

TAN Function Syntax
=======================================================================

 TAN(angle)
 ~~~

=======================================================================

The <angle> is assumed to be a value expressed in radians. If you need to determine the tangent of an angle measured in degrees, you first need to convert that angle to radians as follows:

"COMPUTE <radians> = ( <degrees> * FUNCTION PI) / 180"


6.16.81. TEST-DATE-YYYYMMDD

TEST-DATE-YYYYMMDD Function Syntax
=======================================================================

 TEST-DATE-YYYYMMDD(date)
 ~~~~~~~~~~~~~~~~~~

=======================================================================

A valid date is one of the form yyyymmdd in the range 1601/01/01 to 9999/12/31, with no more than the expected maximum number of days in the month, accounting for leap year.

If the <date> is valid, a 0 value is returned. If it isn’t, a value of 1, 2 or 3 is returned signalling the problem lies with the year, month or day, respectively.



6.16.82. TEST-DAY-YYYYDDD

TEST-DAY-YYYYDDD Function Syntax
=======================================================================

 TEST-DATE-YYYYDDD(date)
 ~~~~~~~~~~~~~~~~~

=======================================================================

A valid date is one of the form yyyyddd in the range 1601001 to 9999365. Leap year is accounted for in determining the maximum number of days in a year.

If the date is valid, a 0 value is returned. If it isn’t, a value of 1 or 2 is returned signalling the problem lies with the year or day, respectively.



6.16.83. TEST-NUMVAL

TEST-NUMVAL Function Syntax
=======================================================================

 TEST-NUMVAL(string)
 ~~~~~~~~~~~

=======================================================================

Note that these errors include but are not limited to: argument (string) is zero length, contains only spaces or contains valid characters but is incomplete, such as the string "+.".



6.16.84. TEST-NUMVAL-C

TEST-NUMVAL-C Function Syntax
=======================================================================

 TEST-NUMVAL-C(string[,symbol])
 ~~~~~~~~~~~~~

=======================================================================

Note that these errors include but are not limited to: argument (string) is zero length, contains only spaces or contains valid characters but is incomplete, such as the string "+.".

The optional <symbol> argument serves the same function — and has the same default and possible values — as the corresponding argument of the "NUMVAL-C" function.



6.16.85. TEST-NUMVAL-F

TEST-NUMVAL-F Function Syntax
=======================================================================

 TEST-NUMVAL-F(string)
 ~~~~~~~~~~~~~

=======================================================================

Note that these errors include but are not limited to: argument (string) is zero length, contains only spaces or contains valid characters but is incomplete, such as the string "+.".



6.16.86. TRIM

TRIM Function Syntax
=======================================================================

 TRIM(string [, LEADING|TRAILING ])
 ~~~~           ~~~~~~~ ~~~~~~~~

=======================================================================

The second argument is specified as a keyword, not a quoted string or identifier. If no second argument is specified, both leading and trailing spaces will be removed. The case (upper, lower or mixed) of this argument is irrelevant.



6.16.87. UPPER-CASE

UPPER-CASE Function Syntax
=======================================================================

 UPPER-CASE(string)
 ~~~~~~~~~~

=======================================================================

What constitutes a "letter" (or upper/lower case too, for that manner) may be influenced through the use of a "CHARACTER CLASSIFICATION" (see OBJECT-COMPUTER).



6.16.88. VARIANCE

VARIANCE Function Syntax
=======================================================================

 VARIANCE(number-1 [, number-2 ]...)
 ~~~~~~~~

=======================================================================


6.16.89. WHEN-COMPILED

WHEN-COMPILED Function Syntax
=======================================================================

 WHEN-COMPILED
 ~~~~~~~~~~~~~

=======================================================================

Since this function has no arguments, no parenthesis should be specified.

Unlike the "WHEN-COMPILED" special register, which has an ASCII value of the compilation date/time in the format "mm/dd/yyhh.mm.ss", the "WHEN-COMPILED" intrinsic function returns the compilation date/time as an ASCII string in the format "yyyymmddhhmmssnnooooo", where "yyyymmdd" is the date, "hhmmss" is the time, "nn" is the hundredths of a second component of the compilation time, if available (or "00" if it isn’t) and "ooooo" is the time zone offset from GMT.

If the "-fintrinsics=WHEN-COMPILED" switch or "-fintrinsics=ALL" switch is specified to the compiler or the "REPOSITORY" (see REPOSITORY) paragraph specifies either "FUNCTION WHEN-COMPILED INTRINSIC" or "FUNCTION ALL INTRINSIC", then references to "WHEN-COMPILED" (without a leading "FUNCTION" keyword will always reference this intrinsic function and there will be no way to access the "WHEN-COMPILED" special register.



6.16.90. YEAR-TO-YYYY

YEAR-TO-YYYY Function Syntax
=======================================================================

 YEAR-TO-YYYY(yy [, yy-cutoff ])
 ~~~~~~~~~~~~

=======================================================================

The optional <yy-cutoff> argument is the year cutoff used to delineate centuries; if <yy> meets or exceeds this cutoff value, the result will be 19yy; if <yy> is less than the cutoff, the result will be 20yy. The default cutoff value if no second argument is given will be 50.

Both arguments must be numeric data items or numeric literals.



6.17. GnuCOBOL Statements



6.17.1. ACCEPT



6.17.1.1. ACCEPT FROM CONSOLE

ACCEPT FROM CONSOLE Syntax
=======================================================================

   ACCEPT { identifier-1 }   [ FROM mnemonic-name-1 ]
   ~~~~~~                      ~~~~
          { OMITTED      }
            ~~~~~~~

 [ END-ACCEPT ]
   ~~~~~~~~~~

=======================================================================
  1. If no "FROM" clause is specified, "FROM CONSOLE" is assumed.
  2. The specified <mnemonic-name-1> must either be one of the built-in device names "CONSOLE", "STDIN", "SYSIN" or "SYSIPT", or a user-defined (see SPECIAL-NAMES) mnemonic name attached to one of those four device names.
  3. Input will be read either from the console window ("CONSOLE") or from the system-standard input (pipe 0 = "STDIN", "SYSIN" or "SYSIPT") and will be saved in <identifier-1>.
  4. If <identifier-1> is a numeric data item, the character value read from the console or standard-input device will be parsed according to the rules for input to the "NUMVAL" intrinsic function (see NUMVAL), except that none of the trailing sign formats are honoured.


6.17.1.2. ACCEPT FROM COMMAND-LINE

ACCEPT FROM COMMAND-LINE Syntax
=======================================================================

   ACCEPT identifier-1
   ~~~~~~
          FROM { COMMAND-LINE                                }
          ~~~~ { ~~~~~~~~~~~~                                }
               { ARGUMENT-NUMBER                             }
               { ~~~~~~~~~~~~~~~                             }
               { ARGUMENT-VALUE                              }
               { ~~~~~~~~~~~~~~                              }
               { [ ON EXCEPTION imperative-statement-1 ]     }
               {      ~~~~~~~~~                              }
               { [ NOT ON EXCEPTION imperative-statement-2 ] }
 [ END-ACCEPT ]    ~~~    ~~~~~~~~~
   ~~~~~~~~~~

=======================================================================
  1. The reserved word "ON" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. When you accept from the "COMMAND-LINE"
  3. By accepting from "ARGUMENT-NUMBER"
    1. Arguments will be separated by treating spaces and/or tab characters as the delimiters between arguments. The number of such delimiters separating two non-blank argument values is irrelevant.
    2. Strings enclosed in double-quote characters (") will be treated as a single argument, regardless of how many spaces or tab characters (if any) might be embedded within those quotation characters.
    3. On Windows systems, single-quote, or apostrophe characters (’) will be treated just like any other data character and will NOT delineate argument strings.
  4. By accepting from "ARGUMENT-VALUE"
  5. The optional "ON EXCEPTION" and "NOT ON EXCEPTION" clauses may be used to detect and react to the failure or success, respectively, of an attempt to retrieve an "ARGUMENT-VALUE". See ON EXCEPTION + NOT ON EXCEPTION, for additional information.


6.17.1.3. ACCEPT FROM ENVIRONMENT

ACCEPT FROM ENVIRONMENT Syntax
=======================================================================

   ACCEPT identifier-1
   ~~~~~~
          FROM { ENVIRONMENT-VALUE            }
          ~~~~ { ~~~~~~~~~~~~~~~~~            }
               { ENVIRONMENT { literal-1    } }
               { ~~~~~~~~~~~ { identifier-1 } }
        [ ON EXCEPTION imperative-statement-1 ]
             ~~~~~~~~~
        [ NOT ON EXCEPTION imperative-statement-2 ]
          ~~~    ~~~~~~~~~
 [ END-ACCEPT ]
   ~~~~~~~~~~

=======================================================================
  1. The reserved word "ON" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. By accepting from "ENVIRONMENT-VALUE"
  3. A simpler approach to retrieving an environment variables value is to use the "ENVIRONMENT"
  4. The optional "ON EXCEPTION" and "NOT ON EXCEPTION" clauses may be used to detect and react to an attempt to retrieve the value of a non-existent environment variable or the successful retrieval of an environment variable’s value, respectively. See ON EXCEPTION + NOT ON EXCEPTION, for additional information.


6.17.1.4. ACCEPT screen-data-item

ACCEPT screen-data-item Syntax
=======================================================================

   ACCEPT { identifier-1 }
   ~~~~~~
          { OMITTED      }
            ~~~~~~~
                           [{ FROM EXCEPTION-STATUS }]
                              ~~~~ ~~~~~~~~~~~~~~~~
                           [{ FROM CRT ] [ MODE IS BLOCK ]}
                              ~~~~ ~~~     ~~~~    ~~~~~

          [ AT { | LINE NUMBER { integer-1    }            | } ]
            ~~ { | ~~~~        { identifier-2 }            | }
               { | COLUMN|COL|POSITION NUMBER { integer-2    } | }
               { | ~~~~~~ ~~~ ~~~~~~~~        { identifier-3 } | }
               {                                             }
               { { integer-3    }                            }
               { { identifier-4 }                            }

          [ WITH [ Attribute-Specification ]...
            ~~~~
                 [ LOWER|UPPER ]
                   ~~~~~ ~~~~~
                 [ SCROLL { UP   } [ { integer-4    } LINE|LINES ] ]
                   ~~~~~~ { ~~   }   { identifier-5 }
                          { DOWN }
                            ~~~~
                 [ TIMEOUT|TIME-OUT AFTER { integer-5    } ]
                   ~~~~~~~ ~~~~~~~~       { identifier-6 }
                 [ CONVERSION ]
                   ~~~~~~~~~~
                 [ UPDATE ] ]
                   ~~~~~~
          [ ON EXCEPTION imperative-statement-1 ]
               ~~~~~~~~~
          [ NOT ON EXCEPTION imperative-statement-2 ]
            ~~~    ~~~~~~~~~
 [ END-ACCEPT ]
   ~~~~~~~~~~

The "FROM CRT"


=======================================================================
  1. The reserved words "AFTER", "IS", "NUMBER" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved words "COLUMN", "COL" and "POSITION" are interchangeable.
  3. The reserved words "TIMEOUT" and "TIME-OUT" are interchangeable.
  4. If <identifier-1> is defined in the "SCREEN SECTION" (see SCREEN SECTION), any "AT", <Attribute-Specification>, "LOWER", "UPPER" or "SCROLL" clauses will be ignored. In these cases, an implied "DISPLAY" (see DISPLAY screen-data-item) of <identifier-1> will occur before input is accepted. Coding an explicit "DISPLAY identifier-1" before an "ACCEPT identifier-1" is redundant and will incur the performance penalty of painting the screen contents twice.
  5. The various "AT" clauses provide a means of positioning the cursor to a specific spot on the screen before the screen is read. One or the other (but not both) may be used, as follows:
    1. The "LINE" and "COLUMN" clauses provide one mechanism for specifying the line and column position to which the cursor will be positioned before allowing the user to enter data. In the absence of one or the other, a value of 1 will be assumed for the one that is missing. The author’s personal preference, however, is to explicitly code both.
    2. The <literal-3> or <identifier-4> value, if specified, must be a four- or six-digit value with the 1st half of the number indicating the line where the cursor should be positioned and the second half indicating the column. You may code only one of each clause on any "ACCEPT".
  6. "WITH" options (including the various individual <Attribute-Specifications>) should be coded only once.
  7. The following <Attribute-Specification> clauses are allowed on the "ACCEPT" statement — these are the same as those allowed for "SCREEN SECTION" data items. A particular <Attribute-Specification> may be used only once in any "ACCEPT":
  8. The "SCROLL"
  9. The "TIMEOUT"
  10. This format of the "ACCEPT" statement will be terminated by any of the following events:
    1. When the ’Enter’ key is pressed.
    2. Expiration of the "TIMEOUT" timer — this will be treated as if the Enter key had been pressed with no data being entered.
    3. When a function key (Fn) is pressed.
    4. The pressing of the PgUp or PgDn keys, if the
    5. The pressing of the Esc key if both the
    6. The pressing of the Up-arrow, Down-Arrow or PrtSc (Print Screen) keys. These keys are not detectable on Windows systems, however.
  11. The following apply when <identifier-1> is defined in the "SCREEN SECTION":
    1. Alphanumeric data entered into <identifier-1> or any screen data item subordinate to it must be consistent with the "PICTURE" (see PICTURE) clause of that item. This will be enforced at runtime by the "ACCEPT" statement.
    2. If <identifier-1> or any screen data item subordinate to it are defined as numeric, entered data must be acceptable as "NUMVAL" intrinsic function (see NUMVAL) input (no decimal points are allowed, however). The value stored into the screen data item will be as if the input were passed to that function.
    3. If <identifier-1> or any screen data item subordinate to it are defined as numeric edited, entered data must be acceptable as "NUMVAL-C" intrinsic function (see NUMVAL-C) input (again, no decimal points are allowed). The value stored into the screen data item will be as if the input were passed to that function.
  12. The following apply when <identifier-1> is not defined in the "SCREEN SECTION":
    1. Alphanumeric data entered into <identifier-1> should be consistent with the "PICTURE" (see PICTURE) clause of that item, although that will not be enforced by the "ACCEPT" statement. You may use "Class Conditions" (see Class Conditions) after the data is accepted to enforce the data type.
    2. If <identifier-1> is defined as numeric, entered data must be acceptable as "NUMVAL" intrinsic function (see NUMVAL) input (no decimal points are allowed, however). The value stored into <identifier-1> will be as if the input were passed to that function.
    3. If <identifier-1> is defined as numeric edited, entered data must be acceptable as "NUMVAL-C" intrinsic function (see NUMVAL-C) input (again, no decimal points are allowed). The value stored into <identifier-1> will be as if the input were passed to that function.
  13. The optional "ON EXCEPTION" and "NOT ON EXCEPTION" clauses may be used to detect and react to the failure or success, respectively, of the screen I/O attempt. See ON EXCEPTION + NOT ON EXCEPTION, for additional information.

    After this format of the "ACCEPT" statement is executed, the program’s "CRT STATUS" (see SPECIAL-NAMES) identifier will be populated with one of the following:

    CodeMeaning
    0000ENTER key pressed
    1001–1064F1–F64, respectively, were pressed
    2001PgUp was pressed
    2002PgDn,was pressed
    2003Up Arrow was pressed
    2004Down-Arrow was pressed
    2006PrtSc (Print Screen) was pressed
    2005Esc was pressed
    8000No data is available on screen ACCEPT
    9000Fatal screen I/O error
  14. The actual key pressed to generate a function key (Fn) will depend on the type of terminal device you’re using (PC, Macintosh, VT100, etc.) and what type of enhanced display driver was configured with the version of GnuCOBOL you’re using. For example, on a GnuCOBOL build for a Windows PC using MinGW and PDCurses, F1-F12 are the actual F-keys on the PC keyboard, F13-F24 are entered by shifting the F-keys, F25-F36 are entered by holding Ctrl while pressing an F-key and F37-F48 are entered by holding Alt while pressing an F-key. On the other hand, a GnuCOBOL implementation built for Windows using Cygwin and NCurses treats the PCs F1-F12 keys as the actual F1-F12, while shifted F-keys will enter F11-F20. With Cygwin/NCurses, Ctrl- and Alt-modified F-keys aren’t recognized. Neither are Shift-F11 or Shift-F12.
  15. Numeric keypad keys are not recognizable on Windows MinGW/PDCurses builds of GnuCOBOL, regardless of the number lock settings. Windows Cygwin/NCurses builds recognize numeric keypad inputs properly. Although not tested during the preparation of this documentation, I would expect native Windows builds using PDCurses to behave as MinGW builds do and native Unix builds using NCurses to behave as do Cygwin builds.
  16. The optional "EXCEPTION-STATUS" clause may be used to detect exceptions from a prior arthmetic verb such as COMPUTE to recover any errors produced. These are recovered using the function "EXCEPTION-STATUS".


6.17.1.5. ACCEPT FROM DATE/TIME

ACCEPT FROM DATE/TIME Syntax
=======================================================================

   ACCEPT identifier-1 FROM { DATE [ YYYYMMDD ] }
   ~~~~~~              ~~~~ { ~~~~   ~~~~~~~~   }
                            { DAY [ YYYYDDD ]   }
                            { ~~~   ~~~~~~~     }
                            { DAY-OF-WEEK       }
                            { ~~~~~~~~~~~       }
 [ END-ACCEPT ]             { TIME              }
   ~~~~~~~~~~

=======================================================================
  1. The data retrieved from the system and the format in which it is structured will vary, as follows:
    SyntaxData RetrievedFormat
    "DATE"Current date in Gregorian formyymmdd
    "DATE YYYYMMDD"Current date in Gregorian formyyyymmdd
    "DAY"Current date in Julian formyyddd
    "DAY YYYYDDD"Current date in Julian formyyyyddd
    "TIME"Time, including hundredths of a second (nn)hhmmssnn


6.17.1.6. ACCEPT FROM Screen-Info

ACCEPT FROM Screen-Info Syntax
=======================================================================

   ACCEPT identifier-1
   ~~~~~~
          FROM { LINES|LINE-NUMBER }
          ~~~~ { ~~~~~ ~~~~~~~~~~~ }
               { COLS|COLUMNS      }
               { ~~~~ ~~~~~~~      }
               { ESCAPE KEY        }
                 ~~~~~~ ~~~
 [ END-ACCEPT ]
   ~~~~~~~~~~

=======================================================================
  1. The reserved words "LINES" and "LINE-NUMBER" are interchangeable.
  2. The reserved words "COLS" and "COLUMNS" are interchangeable.
  3. The following points pertain to the use of the "LINES"
    1. The "LINES"
    2. When the console is running in a windowed environment, this will be the sizing of the window in which the program is executing, in terms of horizontal ("COLUMNS") or vertical ("LINES") character counts — not pixels.
    3. When the system is not running a windowing environment, the physical console screen attributes will be returned.
    4. Values of 0 will be returned if GnuCOBOL was not generated to include screen I/O.
    5. See the documentation on the "CBL_GET_SCR_SIZE" built-in system subroutine (see CBL_GET_SCR_SIZE) for another way to retrieve this information.
  4. The "ESCAPE KEY"


6.17.1.7. ACCEPT FROM Runtime-Info

ACCEPT FROM Runtime-Info Syntax
=======================================================================

   ACCEPT identifier-1
   ~~~~~~
          FROM { EXCEPTION STATUS }
          ~~~~ { ~~~~~~~~~ ~~~~~~ }
               { USER NAME        }
                 ~~~~ ~~~~
 [ END-ACCEPT ]
   ~~~~~~~~~~

=======================================================================
  1. The following points pertain to the use of the "EXCEPTION STATUS"
    1. <identifier-1> must be defined as a "PIC X(4)" item.
    2. See Error Exception Codes, for a complete list of the exception codes and their meanings.
    3. An alternative to the use of "ACCEPT FROM Runtime-Info" is to use the "EXCEPTION-STATUS" intrinsic function (see EXCEPTION-STATUS).
  2. The following points pertain to the use of the "USER NAME"
    1. The returned result is the userid that was used to login to the system with, and not any actual first and/or last name of the user in question (unless, of course, that is the information used as a logon id).
    2. <identifier-1> should be defined large enough to receive the longest user-name on the system.
    3. If insufficient space is allocated, the returned value will be truncated.
    4. If excess space is allocated, the returned value will be padded with spaces (to the right).


6.17.1.8. ACCEPT OMITTED

ACCEPT OMITTED Syntax
=======================================================================

   ACCEPT OMITTED
   ~~~~~~

   1.  For console : See 6.17.1.1 (ACCEPT FROM CONSOLE Syntax)

   2.  For Screen  : See 6.17.1.4 (ACCEPT screen-data-item Syntax)

 [ END-ACCEPT ]
   ~~~~~~~~~~

=======================================================================
  1. The following are examples of keycodes that can be used:
    COB-SCR-INSERT
    COB-SCR-DELETE
    COB-SCR-BACKSPACE
    COB-SCR-KEY-HOME
    COB-SCR-KEY-END
    
  2. You can used extended attributes, useful for setting timeouts or positioning.


6.17.1.9. ACCEPT FROM EXCEPTION-STATUS

ACCEPT FROM EXCEPTION-STATUS Syntax
=======================================================================

   ACCEPT exception-status-pic-9-4   FROM EXCEPTION-STATUS
   ~~~~~~                            ~~~~ ~~~~~~~~~~~~~~~~

 [ END-ACCEPT ]
   ~~~~~~~~~~

=======================================================================
  1. The following is an example of usage:
     In WS:
     01  exception-status  pic 9(4).
    ..
     In PD:
    
     ACCEPT unexpected-rounding  FROM EXCEPTION-STATUS
     IF unexpected-rounding NOT EQUAL "0000" THEN
        DISPLAY "Unexpected rounding. Code " unexpected-rounding
                 UPON SYSERR
     END-IF
    


6.17.2. ADD



6.17.2.1. ADD TO

ADD TO Syntax
=======================================================================

   ADD { literal-1    }...
   ~~~ { identifier-1 }

       TO { identifier-2
       ~~
          [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ] }...
            ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                              { NEAREST-AWAY-FROM-ZERO }
                              { ~~~~~~~~~~~~~~~~~~~~~~ }
                              { NEAREST-EVEN           }
                              { ~~~~~~~~~~~~           }
                              { NEAREST-TOWARD-ZERO    }
                              { ~~~~~~~~~~~~~~~~~~~    }
                              { PROHIBITED             }
                              { ~~~~~~~~~~             }
                              { TOWARD-GREATER         }
                              { ~~~~~~~~~~~~~~         }
                              { TOWARD-LESSER          }
                              { ~~~~~~~~~~~~~          }
                              { TRUNCATION             }
                                ~~~~~~~~~~
     [ ON SIZE ERROR imperative-statement-1 ]
          ~~~~ ~~~~~
     [ NOT ON SIZE ERROR imperative-statement-2 ]
       ~~~    ~~~~ ~~~~~
 [ END-ADD ]
   ~~~~~~~

=======================================================================
  1. The reserved words "IS" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. Both <identifier-1> and <identifier-2> must be numeric unedited data items while <literal-1> must be a numeric literal.
  3. An <identifier-1> data item may also be coded as an <identifier-2> — note, however, that the value of such a data item will therefore be included twice in the result.
  4. The contents of each <identifier-1> will remain unchanged by this statement.
  5. The optional "ROUNDED" (see ROUNDED) clause available to each <identifier-2> will control how non-integer results will be saved.
  6. The optional "ON SIZE ERROR" and "NOT ON SIZE ERROR" clauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-2> with an insufficient number of digit positions available to the left of any implied decimal point. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information.


6.17.2.2. ADD GIVING

ADD GIVING Syntax
=======================================================================

   ADD { literal-1    }...
   ~~~ { identifier-1 }

     [ TO identifier-2 ]
       ~~
       GIVING { identifier-3
       ~~~~~~
         [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ] }...
           ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                             { NEAREST-AWAY-FROM-ZERO }
                             { ~~~~~~~~~~~~~~~~~~~~~~ }
                             { NEAREST-EVEN           }
                             { ~~~~~~~~~~~~           }
                             { NEAREST-TOWARD-ZERO    }
                             { ~~~~~~~~~~~~~~~~~~~    }
                             { PROHIBITED             }
                             { ~~~~~~~~~~             }
                             { TOWARD-GREATER         }
                             { ~~~~~~~~~~~~~~         }
                             { TOWARD-LESSER          }
                             { ~~~~~~~~~~~~~          }
                             { TRUNCATION             }
                               ~~~~~~~~~~
     [ ON SIZE ERROR imperative-statement-1 ]
          ~~~~ ~~~~~
     [ NOT ON SIZE ERROR imperative-statement-2 ]
       ~~~    ~~~~ ~~~~~
 [ END-ADD ]
   ~~~~~~~

=======================================================================
  1. The reserved words "IS" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. Both <identifier-1> and <identifier-2> must be numeric unedited data items while <literal-1> must be a numeric literal; <identifier-3> may be either a numeric or numeric edited data item.
  3. An <identifier-1> or <identifier-2> data item may be used as an <identifier-3>, if desired.
  4. The contents of each <identifier-1> and <identifier-2> will remain unchanged by this statement, unless they happen to also be specified as an <identifier-3>.
  5. The current value in each <identifier-3> at the start of the statement’s execution is irrelevant, since the contents of each <identifier-3> will simply be replaced with the computed sum.
  6. The optional "ROUNDED" (see ROUNDED) clause available to each <identifier-3> will control how non-integer results will be saved.
  7. The optional "ON SIZE ERROR" and "NOT ON SIZE ERROR" clauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-3> with an insufficient number of digit positions available to the left of any implied decimal point. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information.


6.17.2.3. ADD CORRESPONDING

ADD CORRESPONDING Syntax
=======================================================================

   ADD CORRESPONDING identifier-1
   ~~~
       TO identifier-2
       ~~
     [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ]
       ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                         { NEAREST-AWAY-FROM-ZERO }
                         { ~~~~~~~~~~~~~~~~~~~~~~ }
                         { NEAREST-EVEN           }
                         { ~~~~~~~~~~~~           }
                         { NEAREST-TOWARD-ZERO    }
                         { ~~~~~~~~~~~~~~~~~~~    }
                         { PROHIBITED             }
                         { ~~~~~~~~~~             }
                         { TOWARD-GREATER         }
                         { ~~~~~~~~~~~~~~         }
                         { TOWARD-LESSER          }
                         { ~~~~~~~~~~~~~          }
                         { TRUNCATION             }
                           ~~~~~~~~~~
     [ ON SIZE ERROR imperative-statement-1 ]
          ~~~~ ~~~~~
     [ NOT ON SIZE ERROR imperative-statement-2 ]
       ~~~    ~~~~ ~~~~~
 [ END-ADD ]
   ~~~~~~~

=======================================================================
  1. The reserved words "IS" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. Both <identifier-1> and <identifier-2> must be group items.
  3. See CORRESPONDING, for information on how corresponding matches will be found between <identifier-1> and <identifier-2>.
  4. The optional "ROUNDED" (see ROUNDED) clause available to each <identifier-3> will control how non-integer results will be saved.
  5. The optional "ON SIZE ERROR" and "NOT ON SIZE ERROR" clauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-3> with an insufficient number of digit positions available to the left of any implied decimal point. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information.


6.17.3. ALLOCATE

ALLOCATE Syntax
=======================================================================

 ALLOCATE { expression-1 CHARACTERS } [ { INITIALIZED } ]
 ~~~~~~~~ { identifier-1 ~~~~~~~~~~ }   { ~~~~~~~~~~~ }
                                        { INITIALISED }
     [ RETURNING identifier-2 ]           ~~~~~~~~~~~
       ~~~~~~~~~

=======================================================================
  1. The reserved words "INITIALIZED" and "INITIALISED" are interchangeable.
  2. Both <identifier-1> and "RETURNING <identifier-2>" may not be specified in the same statement.
  3. If used, <expression-1> must be an arithmetic expression with a non-zero positive integer value.
  4. If used, <identifier-1> should be an 01-level item defined in working-storage or local-storage with the "BASED" (see BASED) attribute. It may be an 01 item defined in the linkage section without the "BASED" attribute, but using such a data item is not recommended.
  5. If used, <identifier-2> should be a "POINTER" (see USAGE) data item.
  6. The optional "RETURNING"
  7. When the <identifier-1> option is used in conjunction with "INITIALIZED"
  8. When the "<expression-1> CHARACTERS" option is used, "INITIALIZED" will initialize the allocated memory block to binary zeros. If "INITIALIZED" is not used, the initial contents of allocated memory will be left to whatever rules of memory allocation are in effect for the operating system the program is running under.
  9. There are two basic ways in which this statement is used. The simplest is:
    ALLOCATE My-01-Item
    

    With this form, a block of storage equal in size to the defined size of My-01-Item (which must have been defined with the "BASED" attribute) will be allocated. The address of that block of storage will become the base address of My-01-Item so that it and its subordinate data items become usable within the program.

    A second (and equivalent) approach is:

    ALLOCATE LENGTH OF My-01-Item CHARACTERS RETURNING The-Pointer
    SET ADDRESS OF My-01-Item TO The-Pointer
    
  10. Referencing a "BASED" data item either before its storage has been allocated or after its storage has been released (via the "FREE" statement) will lead to "unpredictable results". That’s how reference manuals and standards specifications talk about this situation. In the author’s experience, the results are all too predictable — the program aborts from an attempt to reference an unallocated area of memory.


6.17.4. ALTER

ALTER Syntax
=======================================================================

 ALTER procedure-name-1 TO PROCEED TO procedure-name-2
 ~~~~~                  ~~

=======================================================================
  1. The reserved words "PROCEED" and "TO" (the one after "PROCEED") are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. <procedure-name-1> must contain only a single statement, and that statement must be a simple "GO TO".
  3. The effect of this statement will be as if the generated machine-language code for the "GO TO" statement in <procedure-name-1> is changed so that the "GO TO" statement now transfers control to <procedure-name-2>, rather than to whatever procedure name was specified in the program source code.
  4. Support for the "ALTER" verb has been added to GnuCOBOL for the purpose of enabling GnuCOBOL to pass those National Institute of Standards and Technology (NIST) tests for the COBOL programming language that require support for "ALTER".
  5. Because of the catastrophic effect this statement has on program readability and therefore the programmer’s ability to debug problems with program logic, the use of "ALTER" in new programs is STRONGLY discouraged.


6.17.5. CALL

CALL Syntax
=======================================================================

   CALL [ { STDCALL         } ] { literal-1    }
   ~~~~   { ~~~~~~~         }   { identifier-1 }
          { STATIC          }
          { ~~~~~~          }
          { mnemonic-name-1 }

        [ USING CALL-Argument... ]
          ~~~~~
        [ RETURNING|GIVING identifier-2 ]
          ~~~~~~~~~ ~~~~~~
        [ ON OVERFLOW|EXCEPTION imperative-statement-1 ]
             ~~~~~~~~ ~~~~~~~~~
        [ NOT ON OVERFLOW|EXCEPTION imperative-statement-2 ]
          ~~~    ~~~~~~~~ ~~~~~~~~~
 [ END-CALL ]
   ~~~~~~~~

=======================================================================
CALL Argument Syntax
=======================================================================

 [ BY { REFERENCE } ]
      { ~~~~~~~~~ }
      { CONTENT   }
      { ~~~~~~~   }
      { VALUE     }
        ~~~~~

      { OMITTED                                                   }
      { ~~~~~~~                                                   }
      { [ UNSIGNED ] [ SIZE IS { AUTO      } ] [ { literal-2    } }
          ~~~~~~~~     ~~~~    { ~~~~      }     { identifier-2 }
                               { DEFAULT   }
                               { ~~~~~~~   }
                               { integer-1 }

=======================================================================
  1. The reserved words "BY", "IS" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved words "EXCEPTION" and "OVERFLOW" are interchangeable.
  3. The reserved words "GIVING" and "RETURNING" are interchangeable.
  4. The expectation is that the subroutine will eventually return control back to the calling program, at which point the CALLing program will resume execution starting with the statement immediately following the "CALL". Subprograms are not required to return to their callers, however, and are free to halt program execution if they wish.
  5. The <mnemonic-name-1> / "STATIC"
    1. The "STATIC" option will cause the linkage to the subroutine to be performed in such a way as to require the subroutine to be statically-linked with the calling program. Note that this enables static-linking to be used on a subroutine-by-subroutine selective basis.
    2. The "STDCALL" option allows system-standard calling conventions (as opposed to GnuCOBOL calling conventions) to be used when calling a subroutine. The definition of what constitutes "system standard" may vary from operating system to operating system. Use of this requires special knowledge about the linkage requirements of subroutines you are intending to "CALL". Subroutines written in GnuCOBOL do not need this option.
    3. The <mnemonic-name-1> option allows a custom-defined calling convention to be used. Such mnemonic names are defined using the "CALL-CONVENTION" (see SPECIAL-NAMES) clause. That clause associates a decimal integer value with <mnemonic-name-1> such that the individual bits set on or off in the binary equivalent of the integer affect linkage to the subroutine as described in the following chart. Those rows of the chart marked with a "No" in the "Supported" column represent bit positions (switch settings) in the integer value that are currently accepted (to provide compatibility to other COBOL implementations) if coded, but are otherwise unsupported.

      Note that bit 0 is the right-most bit in the binary value.

      BitSupportedMeaning if 0Meaning if 1
      0NoArguments will be passed in right-to-left sequenceArguments will be passed in left-to-right sequence.
      1NoThe calling program will flush processed arguments from the argument stack.The called program (subroutine) will flush processed arguments from the argument stack.
      2YesThe "RETURN-CODE" special register (see Special Registers) will be updated in addition to any "RETURNING" or "GIVING" data item.The "RETURN-CODE" special register will not be updated (but any "RETURNING" or "GIVING" data item still will).
      3YesIf CALL "literal" is used, the subroutine will be located and linked in with the calling program at compile time or may be dynamically located and loaded at execution time, depending on compiler switch settings and operating system capabilities.If CALL "literal" is used, the subroutine can only be located and linked with the calling program at compilation time.
      4NoOS/2 "OPTLINK" conventions will not be used to CALL the subprogram.OS/2 "OPTLINK" conventions will be used to CALL the subprogram.
      5NoWindows 16-bit "thunking" will not be in effect.Windows 16-bit "thunking" will be used to call the subroutine as a DLL.
      6YesThe STDCALL convention will not be used.The STDCALL convention, required to use the Microsoft Win32 API, will be used.

      Using the "STDCALL" option on a "CALL" statement is equivalent to using "CALL-CONVENTION 8" (only bit 3 set).

      Using the "STATIC" option on a "CALL" statement is equivalent to using "CALL CONVENTION 64" (only bit 6 set).

  6. The value of <literal-1> or <identifier-1> is the entry-point of the subprogram you wish to call.
  7. When you call a subroutine using <identifier-1>, you are forcing the runtime system to call a dynamically-loadable subprogram. The contents of <identifier-1> will be the entry-point name within that module. If this is the first call to any entry-point within the module being made at run-time, the contents of <identifier-1> must be the primary entry-point name of the module (which must also match the filename, minus any OS-mandated extension) of the executable file comprising the module).
  8. You can force the GnuCOBOL runtime system to pre-load all dynamically-loaded modules that could ever be called by the program, at the time the program starts executing. This is accomplished through the use of the
  9. If the subprogram being called is a GnuCOBOL program, and if that program had the "INITIAL" (see IDENTIFICATION DIVISION) attribute specified on its "PROGRAM-ID" clause, all of the subprogram’s data division data will be restored to its initial state each time the subprogram is executed, regardless of which entry-point within the subprogram is being referenced.

    This [re]-initialization behaviour will always apply to any subprogram’s local-storage (if any), regardless of the use (or not) of "INITIAL".

  10. The "USING"
    1. "BY REFERENCE"
    2. "BY CONTENT"
    3. "BY VALUE"
    4. If an argument lacks a "BY" clause, the most-recently encountered "BY" specification on that "CALL" statement will be assumed. If the first argument specified on a "CALL" lacks a "BY" clause, "BY REFERENCE" will be assumed.
  11. No more than 36 arguments may be passed to a subroutine, unless the GnuCOBOL compiler was built with a specifically different argument limit specified for it. If you have access to the GnuCOBOL source code, you may adjust this limit by changing the value of the "COB_MAX_FIELD_PARAMS" in the "common.h" file (found in the "libcob" folder) before you run "make" to build the compiler and run-time library.
  12. The "RETURNING"
  13. The optional "ON OVERFLOW" and "NOT ON OVERFLOW" clauses (or "ON EXCEPTION" and "NOT ON EXCEPTION" — they are interchangeable) may be used to detect and react to the failure or success, respectively, of an attempt to "CALL" the subroutine. Failure, in this context, is defined as the inability to either locate or load the object code of the subroutine at execution time. See ON OVERFLOW + NOT ON OVERFLOW, for additional information.


6.17.6. CANCEL

CANCEL Syntax
=======================================================================

 CANCEL { literal-1    }...
 ~~~~~~ { identifier-1 }

=======================================================================
  1. If a dynamically-loadable module unloaded by the "CANCEL" statement is subsequently re-executed, all data division storage for that module will once again be in it’s initial state.
  2. Whether the "CANCEL" statement actually physically unloads a dynamically-loaded module or simply marks it as logically-unloaded depends on the use and value of the


6.17.7. CLOSE

CLOSE Syntax
=======================================================================

 CLOSE { file-name-1 [ { REEL|UNIT [ FOR REMOVAL ] } ] }...
 ~~~~~                 { ~~~~ ~~~~       ~~~~~~~   }
                       { WITH LOCK                 }
                       {      ~~~~                 }
                       { WITH NO REWIND            }
                              ~~ ~~~~~~

The "REEL"


=======================================================================
  1. The reserved words "FOR" and "WITH" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved words "REEL" and "UNIT" are interchangeable.
  3. The "CLOSE" statement may only be executed against files that have been successfully opened.
  4. A successful "CLOSE" will write any remaining unwritten record buffers to the file (similar to an "UNLOCK" statement (see UNLOCK)) and release any file locks for the file, regardless of open mode. A closed file will then be no longer available for subsequent I/O statements until it is once again OPENED.
  5. When a "ORGANIZATION LINE SEQUENTIAL" (see ORGANIZATION LINE SEQUENTIAL) or "LINE ADVANCING" (see LINE ADVANCING) file is closed, a final delimiter sequence will be written to the file to signal the termination point of the final data record in the file. This will only be necessary if the final record written to the file was written with the "AFTER ADVANCING" (see WRITE) option.


6.17.8. COMMIT

COMMIT Syntax
=======================================================================

 COMMIT
 ~~~~~~

=======================================================================

See the "UNLOCK" statement (see UNLOCK) for additional details.



6.17.9. COMPUTE

COMPUTE Syntax
=======================================================================

   COMPUTE { identifier-1
   ~~~~~~~
       [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] }...
         ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                           { NEAREST-AWAY-FROM-ZERO }
                           { ~~~~~~~~~~~~~~~~~~~~~~ }
                           { NEAREST-EVEN           }
                           { ~~~~~~~~~~~~           }
                           { NEAREST-TOWARD-ZERO    }
                           { ~~~~~~~~~~~~~~~~~~~    }
                           { PROHIBITED             }
                           { ~~~~~~~~~~             }
                           { TOWARD-GREATER         }
                           { ~~~~~~~~~~~~~~         }
                           { TOWARD-LESSER          }
                           { ~~~~~~~~~~~~~          }
                           { TRUNCATION             }
                             ~~~~~~~~~~
         =|EQUAL arithmetic-expression-1
           ~~~~~
       [ ON SIZE ERROR imperative-statement-1 ]
            ~~~~ ~~~~~
       [ NOT ON SIZE ERROR imperative-statement-2 ]
         ~~~    ~~~~ ~~~~~
 [ END-COMPUTE ]
   ~~~~~~~~~~~

=======================================================================
  1. The reserved words "IS" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved word "EQUAL" is interchangeable with the use of "=".
  3. Each <identifier-1> must be a numeric or numeric-edited data item.
  4. The optional "ROUNDED" (see ROUNDED) clause available to each <identifier-1> will control how non-integer results will be saved.
  5. See Arithmetic Expressions, for more information on arithmetic expressions.
  6. The optional "ON SIZE ERROR" and "NOT ON SIZE ERROR" clauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined either as having an <identifier-3> with an insufficient number of digit positions available to the left of any implied decimal point or attempting to divide by zero. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information.


6.17.10. CONTINUE

CONTINUE Syntax
=======================================================================

 CONTINUE
 ~~~~~~~~

=======================================================================
  1. The "CONTINUE" statement has no effect on the execution of the program.
  2. This statement (perhaps in combination with an appropriate comment or two) makes a convenient "place holder" — particularly in "ELSE" (see IF) or "WHEN" (see EVALUATE) clauses where no code is currently expected to be needed, but a place for code to handle the conditions in question is to be reserved in case it’s ever needed.


6.17.11. DELETE

DELETE Syntax
=======================================================================

   DELETE file-name-1 RECORD
   ~~~~~~
     [ INVALID KEY imperative-statement-1 ]
       ~~~~~~~
     [ NOT INVALID KEY imperative-statement-2 ]
       ~~~ ~~~~~~~
 [ END-DELETE ]
   ~~~~~~~~~~

=======================================================================
  1. The reserved words "KEY" and "RECORD" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The "ORGANIZATION" of <file-name-1> cannot be "ORGANIZATION LINE SEQUENTIAL" (see ORGANIZATION LINE SEQUENTIAL).
  3. The <file-name-1> file cannot be a sort/merge work file (a file described using a "SD" (see File/Sort-Description)).
  4. For files in the "SEQUENTIAL" access mode, the last input-output statement executed against <file-name-1> prior to the execution of the "DELETE" statement must have been a successfully executed sequential-format "READ" statement (see Sequential READ). That "READ" will therefore identify the record to be deleted.
  5. If <file-name-1> is a "RELATIVE" file whose "ACCESS MODE" (see ORGANIZATION RELATIVE) is either "RANDOM" or "DYNAMIC", the record to be deleted is the one whose relative record number is currently the value of the field specified as the files "RELATIVE KEY"
  6. If <file-name-1> is an "INDEXED" file whose "ACCESS MODE" (see ORGANIZATION INDEXED) is "RANDOM" or "DYNAMIC", the record to be deleted is the one whose primary key is currently the value of the field specified as the "RECORD KEY"
  7. The optional "INVALID KEY" and "NOT INVALID KEY" clauses may be used to detect and react to the failure or success, respectively, of an attempt to delete a record. See INVALID KEY + NOT INVALID KEY, for additional information.
  8. No "INVALID KEY" or "NOT INVALID KEY" clause may be specified for a file who’s "ACCESS MODE IS SEQUENTIAL".


6.17.12. DISPLAY



6.17.12.1. DISPLAY UPON device

DISPLAY UPON device Syntax
=======================================================================

   DISPLAY { literal-1    }...
   ~~~~~~~ { identifier-1 }
      [ UPON mnemonic-name-1 ]
        ~~~~
      [ WITH NO ADVANCING ]
             ~~ ~~~~~~~~~
      [ ON EXCEPTION imperative-statement-1 ]
           ~~~~~~~~~
      [ NOT ON EXCEPTION imperative-statement-2 ]
        ~~~    ~~~~~~~~~
 [ END-DISPLAY ]
   ~~~~~~~~~~~

=======================================================================
  1. The reserved words "ON" and "WITH" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. If no "UPON"

    When displaying upon the "STDERR" or "SYSERR" devices or to a <mnemonic-name-1> attached to one of those two devices, the output will be written to output pipe #2, which will normally cause the output to appear in the console output window. You may, if desired, redirect that output to a file by appending "2> filename" to the end of the command that executes the program. This applies to both Windows (any type) or Unix versions of GnuCOBOL.

    When displaying upon the "CONSOLE", "PRINTER", "STDOUT", "SYSLIST", "SYSLST" or "SYSOUT" devices or to a <mnemonic-name-1> attached to one of them, the output will be written to output pipe #1, which will normally cause the output to appear in the console output window. You may, if desired, redirect that output to a file by appending "1> filename" or simply "> filename" to the end of the command that executes the program. This applies to both Windows (any type) or Unix versions of GnuCOBOL.

  3. The "NO ADVANCING"
  4. The optional "ON EXCEPTION" and "NOT ON EXCEPTION" clauses may be used to detect and react to the failure or success, respectively, of an attempt to display output to the specified device. See ON EXCEPTION + NOT ON EXCEPTION, for additional information.


6.17.12.2. DISPLAY UPON COMMAND-LINE

DISPLAY UPON COMMAND-LINE Syntax
=======================================================================

   DISPLAY { literal-1    }...
   ~~~~~~~ { identifier-1 }
        UPON { ARGUMENT-NUMBER|COMMAND-LINE }
        ~~~~ { ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ }
      [ ON EXCEPTION imperative-statement-1 ]
           ~~~~~~~~~
      [ NOT ON EXCEPTION imperative-statement-2 ]
        ~~~    ~~~~~~~~~
 [ END-DISPLAY ]
   ~~~~~~~~~~~

=======================================================================
  1. The reserved word "ON" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. By displaying a numeric integer value UPON "ARGUMENT-NUMBER"
  3. Executing a "DISPLAY UPON COMMAND-LINE" will influence subsequent "ACCEPT FROM COMMAND-LINE" statements (which will then return the value you displayed), but will not influence subsequent "ACCEPT FROM ARGUMENT-VALUE" statements — these will continue to return the original program execution parameters.
  4. The optional "ON EXCEPTION" and "NOT ON EXCEPTION" clauses may be used to detect and react to the failure or success, respectively, of an attempt to display output to the specified item. See ON EXCEPTION + NOT ON EXCEPTION, for additional information.


6.17.12.3. DISPLAY UPON ENVIRONMENT-NAME

DISPLAY UPON ENVIRONMENT-NAME Syntax
=======================================================================

   DISPLAY { literal-1    }... UPON { ENVIRONMENT-VALUE }
   ~~~~~~~ { identifier-1 }    ~~~~ { ~~~~~~~~~~~~~~~~~ }
                                    { ENVIRONMENT-NAME  }
                                      ~~~~~~~~~~~~~~~~
      [ ON EXCEPTION imperative-statement-1 ]
           ~~~~~~~~~
      [ NOT ON EXCEPTION imperative-statement-2 ]
        ~~~    ~~~~~~~~~
 [ END-DISPLAY ]
   ~~~~~~~~~~~

=======================================================================
  1. The reserved word "ON" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. To create or change an environment variable will require two "DISPLAY" statements. The following example sets the environment variable "MY_ENV_VAR" to a value of "Demonstration Value":
    DISPLAY "MY_ENV_VAR" UPON ENVIRONMENT-NAME
    DISPLAY "Demonstration Value" UPON ENVIRONMENT-VALUE
    
  3. Environment variables created or changed from within GnuCOBOL programs will be available to any sub-shell processes spawned by that program (i.e. "CALL 'SYSTEM'" (see SYSTEM)) but will not be known to the shell or console window that started the GnuCOBOL program.
  4. Consider using "SET ENVIRONMENT" (see SET ENVIRONMENT) in lieu of "DISPLAY" to set environment variables as it is much simpler.
  5. The optional "ON EXCEPTION" and "NOT ON EXCEPTION" clauses may be used to detect and react to the failure or success, respectively, of an attempt to display output to the specified item. See ON EXCEPTION + NOT ON EXCEPTION, for additional information.


6.17.12.4. DISPLAY screen-data-item

DISPLAY screen-data-item Syntax
=======================================================================

   DISPLAY identifier-1 [ UPON CRT|CRT-UNDER ]
   ~~~~~~~                ~~~~ ~~~ ~~~~~~~~~
       [ AT { | LINE NUMBER { integer-1    }            | } ]
         ~~ { | ~~~~        { identifier-2 }            | }
            { |                                         | }
            { | COLUMN|POSITION NUMBER { integer-2    } | }
            { | ~~~~~~ ~~~~~~~~        { identifier-3 } | }
            {                                             }
            { { integer-3    }                            }
            { { identifier-4 }                            }

       [ WITH [ DISPLAY-Attribute ]...
         ~~~~
              [ SCROLL { UP   } [ { integer-4    } LINE|LINES ] ]
                ~~~~~~ { ~~   }   { identifier-5 }
                       { DOWN }
                         ~~~~
              [ TIMEOUT|TIME-OUT AFTER { integer-5    } ]
                ~~~~~~~ ~~~~~~~~       { identifier-6 }
              [ CONVERSION ] ]
                ~~~~~~~~~~
       [ ON EXCEPTION imperative-statement-1 ]
            ~~~~~~~~~
       [ NOT ON EXCEPTION imperative-statement-2 ]
         ~~~    ~~~~~~~~~
 [ END-DISPLAY ]
   ~~~~~~~~~~~

The "UPON CRT"


=======================================================================
  1. The reserved words "AFTER", "LINE", "LINES", "NUMBER" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved words "COLUMN" and "POSITION" are interchangeable.
  3. The reserved words "LINE" and "LINES" are interchangeable.
  4. The reserved words "TIMEOUT" and "TIME-OUT" are interchangeable.
  5. If <identifier-1> is defined in the "SCREEN SECTION" (see SCREEN SECTION), any "AT", <Attribute-Specification> and "WITH" clauses will be ignored. All field definition, cursor positioning and screen control will occur as a result of the screen section definition of <identifier-1>.
  6. The following points apply if <identifier-1> is not defined in the screen section:
    1. The purpose of the "AT" clause is to define where on the screen <identifier-1> should be displayed. See ACCEPT screen-data-item, for additional information.
    2. The purpose of the "WITH" clause is to define the visual attributes that should be applied to <identifier-1> when it is displayed on the screen as well as other presentation-control characteristics.
    3. The following <Attribute-Specification> clauses are allowed on the "DISPLAY" statement — these are the same as those allowed for "SCREEN SECTION" data items. A particular <Attribute-Specification> may be used only once in any "DISPLAY":
    4. See ACCEPT screen-data-item, for additional information on the other "WITH" clause options.
  7. The optional "ON EXCEPTION" and "NOT ON EXCEPTION" clauses may be used to detect and react to the failure or success, respectively, of the screen I/O attempt. See ON EXCEPTION + NOT ON EXCEPTION, for additional information.


6.17.13. DIVIDE



6.17.13.1. DIVIDE INTO

DIVIDE INTO Syntax
=======================================================================

 DIVIDE { literal-1    } INTO { identifier-2
 ~~~~~~ { identifier-1 } ~~~~

       [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ] }...
         ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                           { NEAREST-AWAY-FROM-ZERO }
                           { ~~~~~~~~~~~~~~~~~~~~~~ }
                           { NEAREST-EVEN           }
                           { ~~~~~~~~~~~~           }
                           { NEAREST-TOWARD-ZERO    }
                           { ~~~~~~~~~~~~~~~~~~~    }
                           { PROHIBITED             }
                           { ~~~~~~~~~~             }
                           { TOWARD-GREATER         }
                           { ~~~~~~~~~~~~~~         }
                           { TOWARD-LESSER          }
                           { ~~~~~~~~~~~~~          }
                           { TRUNCATION             }
                             ~~~~~~~~~~
    [ ON SIZE ERROR imperative-statement-1 ]
         ~~~~ ~~~~~
    [ NOT ON SIZE ERROR imperative-statement-2 ]
      ~~~    ~~~~ ~~~~~
 [ END-DIVIDE ]
   ~~~~~~~~~~

=======================================================================
  1. The reserved words "IS" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. Both <identifier-1> and <identifier-2> must be numeric unedited data items and <literal-1> must be a numeric literal.
  3. A division operation will be performed for each <identifier-2>, in turn. Each of the results of those divisions will be saved to the corresponding <identifier-2> data item(s).
  4. Should any <identifier-2> be an integer numeric data item, the result computed when that <identifier-2> is divided by <literal-1> or <identifier-1> will also be an integer — any remainder from that division will be discarded.
  5. The optional "ROUNDED" (see ROUNDED) clause available to each <identifier-2> will control how non-integer results will be saved.
  6. The optional "ON SIZE ERROR" and "NOT ON SIZE ERROR" clauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being numeric truncation caused by an <identifier-2> with an insufficient number of digit positions available to the left of any implied decimal point, or an attempt to divide by zero. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information.


6.17.13.2. DIVIDE INTO GIVING

DIVIDE INTO GIVING Syntax
=======================================================================

 DIVIDE { literal-1    } INTO { literal-2    } GIVING { identifier-3
 ~~~~~~ { identifier-1 } ~~~~ { identifier-2 } ~~~~~~

            [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ] }...
              ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                                { NEAREST-AWAY-FROM-ZERO }
                                { ~~~~~~~~~~~~~~~~~~~~~~ }
                                { NEAREST-EVEN           }
                                { ~~~~~~~~~~~~           }
                                { NEAREST-TOWARD-ZERO    }
                                { ~~~~~~~~~~~~~~~~~~~    }
                                { PROHIBITED             }
                                { ~~~~~~~~~~             }
                                { TOWARD-GREATER         }
                                { ~~~~~~~~~~~~~~         }
                                { TOWARD-LESSER          }
                                { ~~~~~~~~~~~~~          }
                                { TRUNCATION             }
    [ REMAINDER identifier-4 ]    ~~~~~~~~~~
      ~~~~~~~~~
    [ ON SIZE ERROR imperative-statement-1 ]
         ~~~~ ~~~~~
    [ NOT ON SIZE ERROR imperative-statement-2 ]
      ~~~    ~~~~ ~~~~~
 [ END-DIVIDE ]
   ~~~~~~~~~~

=======================================================================
  1. The reserved words "IS" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. Both <identifier-1> and <identifier-2> must be numeric unedited data items while both <identifier-3> and <identifier-4> must be numeric (edited or unedited) data items.
  3. Both <literal-1> and <literal-2> must be numeric literals.
  4. If the "REMAINDER"
  5. The result obtained when the value of <literal-2> or <identifier-2> is divided by the value of <literal-1> or <identifier-1> is computed; this result is then moved into each <identifier-3>, in turn, applying the rules defined by the "ROUNDED" (see ROUNDED) clause (if any) for that <identifier-3> to the move.
  6. If a "REMAINDER" clause is specified, the value of the one and only <identifier-3> (as stated earlier, if "REMAINDER" is specified there may only be a single <identifier-3> coded on the statement) after it was assigned a value according to the previous rule will be multiplied by the value of <literal-1> or <identifier-1>; that result is then subtracted from the value of <literal-2> or <identifier-2> and that result is the value which is moved to <identifier-4>.
  7. The optional "ON SIZE ERROR" and "NOT ON SIZE ERROR" clauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-2> with an insufficient number of digit positions available to the left of any implied decimal point, or an attempt to divide by zero. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information.


6.17.13.3. DIVIDE BY GIVING

DIVIDE BY GIVING Syntax
=======================================================================

 DIVIDE { literal-1    } BY { literal-2    } GIVING { identifier-3
 ~~~~~~ { identifier-1 } ~~ { identifier-2 } ~~~~~~

            [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ] }...
              ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                                { NEAREST-AWAY-FROM-ZERO }
                                { ~~~~~~~~~~~~~~~~~~~~~~ }
                                { NEAREST-EVEN           }
                                { ~~~~~~~~~~~~           }
                                { NEAREST-TOWARD-ZERO    }
                                { ~~~~~~~~~~~~~~~~~~~    }
                                { PROHIBITED             }
                                { ~~~~~~~~~~             }
                                { TOWARD-GREATER         }
                                { ~~~~~~~~~~~~~~         }
                                { TOWARD-LESSER          }
                                { ~~~~~~~~~~~~~          }
                                { TRUNCATION             }
    [ REMAINDER identifier-4 ]    ~~~~~~~~~~
      ~~~~~~~~~
    [ ON SIZE ERROR imperative-statement-1 ]
         ~~~~ ~~~~~
    [ NOT ON SIZE ERROR imperative-statement-2 ]
      ~~~    ~~~~ ~~~~~
 [ END-DIVIDE ]
   ~~~~~~~~~~

=======================================================================
  1. The reserved words "IS" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. Both <identifier-1> and <identifier-2> must be numeric unedited data items while both <identifier-3> and <identifier-4> must be numeric (edited or unedited) data items.
  3. Both <literal-1> and <literal-2> must be numeric literals.
  4. If the "REMAINDER"
  5. The result obtained when the value of <literal-1> or <identifier-1> is divided by the value of <literal-2> or <identifier-2> is computed; this result is then moved into each <identifier-3>, in turn, applying the rules defined by the "ROUNDED" (see ROUNDED) clause (if any) for that <identifier-3> to the move.
  6. If a "REMAINDER" clause is specified, the value of the one and only <identifier-3> (as stated earlier, if "REMAINDER" is specified there may only be a single <identifier-3> coded on the statement) after it was assigned a value according to the previous rule will be multiplied by the value of <literal-2> or <identifier-2>; that result is then subtracted from the value of <literal-1> or <identifier-1> and that result is the value which is moved to <identifier-4>.
  7. The optional "ON SIZE ERROR" and "NOT ON SIZE ERROR" clauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-2> with an insufficient number of digit positions available to the left of any implied decimal point, or an attempt to divide by zero. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information.


6.17.14. ENTRY

ENTRY Syntax
=======================================================================

 ENTRY literal-1 [ USING ENTRY-Argument... ]
 ~~~~~             ~~~~~

=======================================================================
ENTRY-Argument Syntax
=======================================================================

 [ BY { REFERENCE } ] identifier-1
      { ~~~~~~~~~ }
      { CONTENT   }
      { ~~~~~~~   }
      { VALUE     }
        ~~~~~

=======================================================================
  1. The reserved word "BY" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. You may not use an "ENTRY" statement in a nested subprogram, nor may you use it in any form of user-defined function.
  3. The "USING"
  4. Each <ENTRY-Argument> specified on the "ENTRY" statement must be defined in the linkage section of the subroutine in which the "ENTRY" statement exists.
  5. The <literal-1> value will specify the entry-point name of the subroutine. It must be specified exactly on "CALL" statements (with regard to the use of upper- and lower-case letters) as it is specified on the "ENTRY" statement.
  6. The meaning of "REFERENCE"


6.17.15. EVALUATE

EVALUATE Syntax
=======================================================================

   EVALUATE Selection-Subject-1 [ ALSO Selection-Subject-2 ]...
   ~~~~~~~~                       ~~~~
 { { WHEN Selection-Object-1 [ ALSO Selection-Object-2 ] }...
     ~~~~                      ~~~~
         [ imperative-statement-1 ] }...
   [ WHEN OTHER
     ~~~~ ~~~~~
         imperative-statement-other ]

 [ END-EVALUATE ]
   ~~~~~~~~~~~~

=======================================================================
EVALUATE Selection Subject Syntax
=======================================================================

 { TRUE         }
 { ~~~~         }
 { FALSE        }
 { ~~~~~        }
 { expression-1 }
 { identifier-1 }
 { literal-1    }

=======================================================================
EVALUATE Selection Object Syntax
=======================================================================

 { ANY                                                }
 { ~~~                                                }
 { TRUE                                               }
 { ~~~~                                               }
 { FALSE                                              }
 { ~~~~~                                              }
 { partial-expression-1                               }
 {                                                    }
 { { expression-2 } [ THRU|THROUGH { expression-3 } ] }
 { { identifier-2 }   ~~~~ ~~~~~~~ { identifier-3 }   }
 { { literal-2    }                { literal-3    }   }

=======================================================================
  1. The reserved words "THRU" and "THROUGH" are interchangeable.
  2. There must be at least one "WHEN"
  3. There must be at least one <Selection-Subject> specified on the "EVALUATE" statement. Any number of additional <Selection-Subject> clauses may be specified, using the "ALSO"
  4. Each "WHEN" clause (other than the "WHEN OTHER"
  5. When using "THRU"
  6. A <partial-expression> is one of the following:
    1. A Class Condition without a leading <identifier-1> (see Class Conditions).
    2. A Sign Condition without a leading <identifier-1> (see Sign Conditions).
    3. A Relation Condition with nothing to the left of the relational operator (see Relation Conditions).
  7. At execution time, each <Selection-Subject> on the "EVALUATE" statement will have its value matched against that of the corresponding <Selection-Object> on a "WHEN" clause, in turn, until:
    1. A "WHEN" clause has each of its <Selection-Object>(s) successfully matched by the corresponding <Selection-Subject>; this will be referred to as the ’Selected WHEN clause’.
    2. The complete list of "WHEN" clauses (except for the "WHEN OTHER" clause, if any) has been exhausted. In this case, there is no ’Selected WHEN Clause’.
  8. If a ’Selected WHEN Clause’ was identified:
    1. The <imperative-statement-1> (see Imperative Statement) immediately following the ’Selected WHEN Clause’ will be executed. If the ’Selected WHEN Clause’ is lacking an <imperative-statement-1>, the first <imperative-statement-1> found after any following "WHEN" clause will be executed.
    2. Once the <imperative-statement-1> has been executed, or no <imperative-statement-1> was found anywhere after the ’Selected WHEN Clause’, control will proceed to the statement following the "END-EVALUATE" or, if there is no "END-EVALUATE", the first statement that follows the next period. If, however, the <imperative-statement-1> included a "GO TO" statement, and that "GO TO" was executed, then control will transfer to the procedure named on the "GO TO" instead.
  9. If no ’Selected WHEN Clause’ was identified:
    1. The "WHEN OTHER" clause’s <imperative-statement-other> will be executed, if such a clause was coded.
    2. Control will then proceed to the statement following the "END-EVALUATE" or the first statement that follows the next period if there is no "END-EVALUATE". If,however, the <imperative-statement-other> included a "GO TO" statement, and that "GO TO" was executed, then control will transfer to the procedure named on the "GO TO" instead.
  10. In order for a <Selection-Subject> to match the corresponding <Selection-Object> on a "WHEN" clause, at least one of the following must be true:
    1. The <Selection-Object> is "ANY"
    2. The implied Relation Condition "<Selection-Subject> = <Selection Object>" is TRUE — See Relation Conditions, for the rules on how the comparison will be made.
    3. The value of the <Selection-Subject> falls within the range of values specified by the "THRU" clause of the <Selection-Object>
    4. If the <Selection-Object> is a <partial-expression>, then the conditional expression that would be represented by coding "<Selection-Subject> <Selection-Object>" evaluates to TRUE
  11. Here is a sample program that illustrates the EVALUATE statement.
    IDENTIFICATION DIVISION.
    PROGRAM-ID. DEMOEVALUATE.
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    01  Test-Digit                  PIC 9(1).
        88 Digit-Is-Odd VALUE 1, 3, 5, 7, 9.
        88 Digit-Is-Prime VALUE 1, 3, 5, 7.
    PROCEDURE DIVISION.
    P1. PERFORM UNTIL EXIT
        DISPLAY "Enter a digit (0 Quits): "
            WITH NO ADVANCING
        ACCEPT Test-Digit
        IF Test-Digit = 0
            EXIT PERFORM
        END-IF
        EVALUATE Digit-Is-Odd ALSO Digit-Is-Prime
        WHEN TRUE ALSO FALSE
            DISPLAY Test-Digit " is ODD"
                WITH NO ADVANCING
        WHEN TRUE ALSO TRUE
            DISPLAY Test-Digit " is PRIME"
                WITH NO ADVANCING
        WHEN FALSE ALSO ANY
            DISPLAY Test-Digit " is EVEN"
                WITH NO ADVANCING
        END-EVALUATE
        EVALUATE Test-Digit
        WHEN < 5
            DISPLAY " and it's small too"
        WHEN < 8
            DISPLAY " and it's medium too"
        WHEN OTHER
            DISPLAY " and it's large too"
        END-EVALUATE
    END-PERFORM
    DISPLAY "Bye!"
    STOP RUN
    .
    

    Console output when run (user input follows the colons on the prompts for input):

    Enter a digit (0 Quits): 1
    1 is PRIME and it's small too
    Enter a digit (0 Quits): 2
    2 is EVEN and it's small too
    Enter a digit (0 Quits): 3
    3 is PRIME and it's small too
    Enter a digit (0 Quits): 4
    4 is EVEN and it's small too
    Enter a digit (0 Quits): 5
    5 is PRIME and it's medium too
    Enter a digit (0 Quits): 6
    6 is EVEN and it's medium too
    Enter a digit (0 Quits): 7
    7 is PRIME and it's medium too
    Enter a digit (0 Quits): 8
    8 is EVEN and it's large too
    Enter a digit (0 Quits): 9
    9 is ODD and it's large too
    Enter a digit (0 Quits): 0
    Bye!
    


6.17.16. EXIT

EXIT Syntax
=======================================================================

 EXIT [ { PROGRAM           } ]
 ~~~~   { ~~~~~~~           }
        { FUNCTION          }
        { ~~~~~~~~          }
        { PERFORM [ CYCLE ] }
        { ~~~~~~~   ~~~~~   }
        { SECTION           }
        { ~~~~~~~           }
        { PARAGRAPH         }
          ~~~~~~~~~

=======================================================================
  1. The "EXIT PROGRAM" statement is not legal anywhere within a user-defined function.
  2. The "EXIT FUNCTION" statement cannot be used anywhere within a subroutine.
  3. Neither "EXIT PROGRAM" nor "EXIT FUNCTION" may be used within a "USE GLOBAL" routine in "DECLARATIVES" (see DECLARATIVES).
  4. The following points describe the "EXIT" statement with none of the optional clauses:
    1. When this form of an "EXIT" statement is used, it must be the only statement in the procedure (paragraph or section) in which it occurs.
    2. This usage of the "EXIT" statement simply provides a common "GO TO" end point for a series of procedures, as may be seen in the following example:
      01  Switches.
          05 Input-File-Switch PIC X(1).
             88 EOF-On-Input-File VALUE ‘Y’ FALSE ‘N’.
      …
          SET EOF-On-Input-File TO FALSE.
          PERFORM 100-Process-A-Transaction THRU 199-Exit
              UNTIL EOF-On-Input-File.
      …
      100-Process-A-Transaction.
          READ Input-File AT END
              SET EOF-On-Input-File TO TRUE
              GO TO 199-Exit
          END-READ.
          IF Input-Rec of Input-File = SPACES
              GO TO 199-Exit  *> IGNORE BLANK RECORDS!
          END-IF.
          <<<process the record just read>>>
      199-Exit.
          EXIT.
      
    3. In this case, the "EXIT" statement takes no other run-time action.
  5. The following points apply to the "EXIT PARAGRAPH" and "EXIT SECTION" statements:
    1. If an "EXIT PARAGRAPH" statement or "EXIT SECTION" statement resides in a paragraph within the scope of a procedural "PERFORM" (see Procedural PERFORM), control will be returned back to the "PERFORM" for evaluation of any "TIMES", "VARYING" and/or "UNTIL" clauses.
    2. If an "EXIT PARAGRAPH" statement or "EXIT SECTION" statement resides outside the scope of a procedural "PERFORM", control simply transfers to the first executable statement in the next paragraph ("EXIT PARAGRAPH") or section ("EXIT SECTION").
    3. The following shows how the previous example could have been coded without a "GO TO" by utilizing an "EXIT PARAGRAPH" statement.
      01  Switches.
          05 Input-File-Switch PIC X(1).
             88 EOF-On-Input-File VALUE ‘Y’ FALSE ‘N’.
      …
          SET EOF-On-Input-File TO FALSE.
          PERFORM 100-Process-A-Transaction
              UNTIL EOF-On-Input-File.
      …
      100-Process-A-Transaction.
          READ Input-File AT END
              SET EOF-On-Input-File TO TRUE
              EXIT PARAGRAPH
          END-READ.
          IF Input-Rec of Input-File = SPACES
              EXIT PARAGRAPH *> IGNORE BLANK RECORDS!
          END-IF.
          <<<process the record just read>>>
      
  6. The following points apply to the "EXIT PERFORM" and "EXIT PERFORM CYCLE" statements:
    1. The "EXIT PERFORM" and "EXIT PERFORM CYCLE" statements are intended to be used in conjunction with an in-line "PERFORM" statement (see Inline PERFORM).
    2. An "EXIT PERFORM CYCLE" statement will terminate the current iteration of the in-line "PERFORM", giving control to any "TIMES", "VARYING" and/or "UNTIL" clauses for them to determine if another cycle needs to be performed.
    3. An "EXIT PERFORM" statement will terminate the in-line PERFORM outright, transferring control to the first statement following the "END-PERFORM" (if there is one) or to the next sentence following the "PERFORM" if there is no "END-PERFORM".
    4. This last example shows the final modification to the previous examples by using an in-line "PERFORM" along with "EXIT PERFORM" and "EXIT PERFORM CYCLE" statements:
      PERFORM FOREVER
          READ Input-File AT END
              EXIT PERFORM
          END-READ
          IF Input-Rec of Input-File = SPACES
              EXIT PERFORM CYCLE *> IGNORE BLANK RECORDS!
          END-IF
          <<<process the record just read>>>
      END PERFORM
      
  7. The following points apply to the "EXIT PROGRAM" and "EXIT FUNCTION" statements:
    1. The "EXIT PROGRAM" and "EXIT FUNCTION" statements terminate the execution of a subroutine (i.e. a program that has been CALLed by another) or user-defined function, respectively, returning control back to the calling program.
    2. An "EXIT PROGRAM" statement returns control back to the statement following the "CALL" (see CALL) of the subprogram. An "EXIT FUNCTION" statement returns control back to the processing of the statement in the calling program that invoked the user-defined function.
    3. If executed by a main program, neither the "EXIT PROGRAM" nor "EXIT FUNCTION" statements will take any action.
    4. The COBOL2002 standard has made a common extension to the COBOL language — the "GOBACK" statement (see GOBACK) — a standard language element; the "GOBACK" statement should be strongly considered as the preferred alternative to both "EXIT PROGRAM" and "EXIT FUNCTION" for new subprograms.


6.17.17. FREE

FREE Syntax
=======================================================================

 FREE { [ ADDRESS OF ] identifier-1 }...
 ~~~~     ~~~~~~~

=======================================================================
  1. The "ADDRESS OF" clause is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this clause has no effect upon the program.
  2. <identifier-1> must have a "USAGE" (see USAGE) of "POINTER", or it must be an 01-level data item with the "BASED" (see BASED) attribute.
  3. If <identifier-1> is a "USAGE POINTER" data item and it contains a valid address, the "FREE" statement will release the memory block the pointer references. In addition, any "BASED" data items that the pointer was used to provide an address for will become un-based and therefore un-usable. If <identifier-1> did not contain a valid address, no action will be taken.
  4. If <identifier-1> is a "BASED" data item and that data item is currently based (meaning it currently has memory allocated to it), its memory is released and <identifier-1> will become un-based and therefore un-usable. If <identifier-1> was not based, no action will be taken.


6.17.18. GENERATE

GENERATE Syntax
=======================================================================

 GENERATE { report-name-1 }
 ~~~~~~~~ { identifier-1  }

=======================================================================
  1. The following points apply when <identifier-1> is specified:
    1. <identifier-1> must be the name of a "DETAIL" (see RWCS Lexicon) report group.
    2. If necessary, <identifier-1> may be qualified with a report name.
    3. The file in whose "FD" a "REPORT" clause exists for the report in which <identifier-1> is a detail group must be opened for "OUTPUT" or "EXTEND" at the time the "GENERATE" is executed. See OPEN, for information on file open modes.
    4. The report in which <identifier-1> is a "DETAIL" group must have been successfully initiated via the "INITIATE" statement (see INITIATE) and not yet terminated via the "TERMINATE" statement (see TERMINATE) at the time the "GENERATE" is executed.
    5. If at least one "GENERATE" statement of this form is executed against a report, the report is said to be a ’detail report
  2. The following points apply when <report-name-1> is specified:
    1. <report-name-1> must be the name of a report having an "RD" defined for it in the report section.
    2. There must be at least one "CONTROL" (see RWCS Lexicon) group defined for <report-name-1>.
    3. There cannot be more than one "DETAIL" group defined for <report-name-1>.
    4. The file in whose "FD" a "REPORT <report-name-1>" clause exists must be open for "OUTPUT" or "EXTEND" at the time the GENERATE is executed.
    5. <report-name-1> must have been successfully initiated (via "INITIATE <report-name-1>") and not yet terminated (via TERMINATE) at the time the "GENERATE" is executed. See OPEN, for information on file open modes.
    6. The "DETAIL" group which is defined for <report-name-1> will be processed but will not actually be presented to any report page. This will allow summary processing to take place. If all "GENERATE" statements are of this form, the report is said to be a ’summary report
  3. When the first "GENERATE" statement for a report is executed, the contents of all control fields are saved so they may be referenced during the processing of subsequent "GENERATE" statements.
  4. When, during the processing of a subsequent "GENERATE", it is determined that a control field has changed value (ie. a control break has occurred), the appropriate control footing and control heading processing will take place and a snapshot of the current values of all control fields will again be saved.


6.17.19. GOBACK

GOBACK Syntax
=======================================================================

 GOBACK
 ~~~~~~

=======================================================================
  1. If executed within a subprogram (i.e. a subroutine or user-defined function), "GOBACK" behaves like an "EXIT PROGRAM" or "EXIT FUNCTION" statement, respectively.
  2. If executed within a main program, "GOBACK" will act as a "STOP RUN" statement.


6.17.20. GO TO



6.17.20.1. Simple GO TO

Simple GO TO Syntax
=======================================================================

 GO TO procedure-name-1
 ~~

=======================================================================
  1. The reserved word "TO" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. If this format of the "GO TO" statement appears in a consecutive sequence of imperative statements (see Imperative Statement) within a sentence, it must be the final statement in the sentence.
  3. If a "GO TO" is executed within the scope of…
    1. ...an in-line "PERFORM" (see PERFORM), the "PERFORM" is terminated as control of execution transfers to <procedure-name-1>.
    2. ...a procedural "PERFORM" (see PERFORM), and <procedure-name-1> lies outside the scope of that "PERFORM", the "PERFORM" is terminated as control of execution transfers to <procedure-name-1>.
    3. ...a "MERGE" statement (see MERGE) "OUTPUT PROCEDURE" or within the scope of either an "INPUT PROCEDURE" or "OUTPUT PROCEDURE" of a "SORT" statement (see File-Based SORT), and <procedure-name-1> lies outside the scope of that procedure, the "SORT" or "MERGE" operation is terminated as control of execution transfers to <procedure-name-1>. Any sorted or merged data accumulated to that point is lost.


6.17.20.2. GO TO DEPENDING ON

GO TO DEPENDING ON Syntax
=======================================================================

 GO TO procedure-name-1...
 ~~
      DEPENDING ON identifier-1
      ~~~~~~~~~

=======================================================================
  1. The reserved word "TO" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. The "PICTURE" (see PICTURE) and/or "USAGE" (see USAGE) of the specified <identifier-1> must be such as to define it as a numeric, unedited, preferably unsigned integer data item.
  3. If the value of <identifier-1> has the value 1, control will be transferred to the 1st specified procedure name. If the value is 2, control will transfer to the 2nd procedure name, and so on.

    If control of execution is transferred to a procedure named on the statement, and the "GO TO" is executed within the scope of…

    1. ...an in-line "PERFORM" (see PERFORM), the "PERFORM" is terminated as control of execution transfers to the procedure named on the statement.
    2. ...a procedural "PERFORM" (see PERFORM), and <procedure-name-1> lies outside the scope of that "PERFORM", the "PERFORM" is terminated as control of execution transfers to the procedure named on the statement.
    3. ...a "MERGE" statement (see MERGE) "OUTPUT PROCEDURE" or within the scope of either an "INPUT PROCEDURE" or "OUTPUT PROCEDURE" of a "SORT" statement (see File-Based SORT), and <procedure-name-1> lies outside the scope of that procedure, the "SORT" or "MERGE" operation is terminated as control of execution transfers to the procedure named on the statement. Any sorted or merged data accumulated to that point is lost.
  4. If the value of <identifier-1> is less than 1 or exceeds the total number of procedure names specified on the statement, control will simply fall through into the next statement following the "GO TO".
  5. The following example shows how "GO TO ... DEPENDING ON" may be used in a real application situation, and compares it against an alternative — "EVALUATE" (see EVALUATE).
    GO TO DEPENDING ON Example        Equivalent EVALUATE Example
    ================================= =================================
        GO TO                         EVALUATE Acct-Type
          ACCT-TYPE-1                 WHEN 1
          ACCT-TYPE-2                     <<< Handle Acct Type 1 >>>
          ACCT-TYPE-3                 WHEN 2
        DEPENDING ON Acct-Type.           <<< Handle Acct Type 2 >>>
        <<< Invalid Acct Type >>>     WHEN 3
        GO TO All-Done.                   <<< Handle Acct Type 3 >>>
    Acct-Type-1.                      WHEN OTHER
        <<< Handle Acct Type 1 >>>        <<< Invalid Acct Type >>>
        GO TO All-Done.               END-EVALUATE.
    Acct-Type-2.
        <<< Handle Acct Type 2 >>>
        GO TO All-Done.
    Acct-Type-3.
        <<< Handle Acct Type 3 >>>
    All-Done.
    
  6. Current programming philosophy would prefer the use of the "EVALUATE" statement to that of this form of the "GO TO" statement.


6.17.21. IF

IF Syntax
=======================================================================

   IF conditional-expression
   ~~
   THEN { imperative-statement-1 }
        { NEXT SENTENCE          }
          ~~~~ ~~~~~~~~
 [ ELSE { imperative-statement-2 } ]
   ~~~~ { NEXT SENTENCE          }
          ~~~~ ~~~~~~~~
 [ END-IF ]
   ~~~~~~

=======================================================================
  1. The reserved word "THEN" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. You cannot use both "NEXT SENTENCE" and the "END-IF" scope terminator in the same "IF" statement.
  3. If <conditional-expression> evaluates to TRUE, <imperative-statement-1> will be executed regardless of whether or not an "ELSE"
  4. If the optional "ELSE" clause is present and conditional-expression evaluates to false, then (and only then) <imperative-statement-2> will be executed. Once <imperative-statement-2> has been executed, control falls into the first statement following the "END-IF" or to the first statement of the next sentence if there is no "END-IF" clause.
  5. The clause "NEXT SENTENCE"

    "NEXT SENTENCE" was needed for COBOL programs that were coded according to pre-1985 standards that wish to nest one "IF" statement inside another. See Use of VERB/END-VERB Constructs, for an explanation of why "NEXT SENTENCE" was necessary.

    Programs coded for 1985 (and beyond) standards don’t need it, instead using the explicit scope-terminator "END-IF" to inform the compiler where <imperative-statement-2> (or <imperative-statement-1> if there is no "ELSE" clause coded) ends. New GnuCOBOL programs should be coded to use the "END-IF" scope terminator for "IF" statements. See Use of VERB/END-VERB Constructs, for additional information.



6.17.22. INITIALIZE

INITIALIZE Syntax
=======================================================================

  INITIALIZE|INITIALISE identifier-1...
  ~~~~~~~~~~ ~~~~~~~~~~
      [ WITH FILLER ]
             ~~~~~~
      [ { category-name-1 } TO VALUE ]
        { ALL             }    ~~~~~
          ~~~
      [ THEN REPLACING { category-name-2 DATA BY
             ~~~~~~~~~                        ~~
            [ LENGTH OF ] { literal-1    } }... ]
              ~~~~~~      { identifier-1 }

      [ THEN TO DEFAULT ]
                ~~~~~~~

=======================================================================
  1. The reserved words "DATA", "OF", "THEN", "TO" and "WITH" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved words "INITIALIZE" and "INITIALISE" are interchangeable.
  3. The "WITH FILLER", "REPLACING" and "DEFAULT" clauses are meaningful only if <identifier-1> is a group item. They are accepted if it’s an elementary item, but will serve no purpose. The "VALUE" clause is meaningful in both cases.
  4. A <category-name-1> and/or <category-name-2> may be any of the following:
    "ALPHABETIC"

    The "PICTURE" (see PICTURE) of the data item only contains "A" symbols.

    "ALPHANUMERIC"

    The "PICTURE" of the data item contains only "X" or a combination of "A" and "9" symbols.

    "ALPHANUMERIC-EDITED"

    The "PICTURE" of the data item contains only "X" or a combination of "A" and "9" symbols plus at least one "B", "0" (zero) or "/" symbol.

    "NUMERIC"

    The data item is one that is described with a picture less "USAGE" (see USAGE) or has a "PICTURE" composed of nothing but "P", "9", "S" and "V" symbols.

    "NUMERIC-EDITED"

    The "PICTURE" of the data item contains nothing but the symbol "9" and at least one of the editing symbols "$", "+", "-", "CR", "DB", ".", ",", "*" or "Z".

    "NATIONAL"

    The data item is one containing nothing but the "N" symbol.

    "NATIONAL-EDITED"

    The data item contains nothing but "N", "B", "/" and "0" symbols.

  5. From the sequence of <identifier-1> data items specified on the "INITIALIZE" statement, a list of initialized fields referred to as the field list in the remainder of this section, will include:
    1. Every <identifier-1> that is an elementary item, including any that may have the "REDEFINES" (see REDEFINES) clause in their descriptions.
    2. Every non-FILLER elementary item subordinate to <identifier-1>, provided that elementary item neither contains a "REDEFINES" clause in its definition nor belongs to a group item subordinate to <identifier-1> which contains a "REDEFINES" clause in its definition.
    3. If the optional "WITH FILLER"
  6. Once a field list has been determined, each item in that field list will be initialized as if an individual "MOVE" (see MOVE) statement to that effect had been coded. The rules for initialization are as follows:
  7. If no "VALUE"
  8. If a "VALUE" clause is specified on the "INITIALIZE" statement, each qualifying member of the field list having a compile-time "VALUE" (see VALUE) specified in it’s definition will be initialized to that value. Field list members with "VALUE" clauses will qualify for this treatment as follows:
    1. If the "ALL" keyword was specified on the "VALUE" clause, all members of the field list with "VALUE" clauses will qualify.
    2. If <category-name-1> is specified instead of "ALL", only those members of the field list with "VALUE" clauses that also meet the criteria set down for the specified <category-name> (see the list above) will qualify.
    3. If you need to apply "VALUE" initialization to multiple <category-name-1> values, you will need to use multiple "INITIALIZE" statements.
  9. If a "REPLACING" clause is specified on the "INITIALIZE" statement, each qualifying member of the field list that was not already initialized by a "VALUE" clause, if any, will be initialized to the specified <literal-1> or <identifier-1> value.

    Only those as-yet uninitialized list members meeting the criteria set forth for the specified <category-name-2> will qualify for this initialization.

    If you need to apply "REPLACING" initialization to multiple <category-name-2> values, you may repeat the syntax after the reserved word "REPLACING", as necessary.

  10. If a "DEFAULT" clause is specified, any remaining uninitialized members of the field list will be initialized according to the default for their class (numeric and numeric-edited are initialized to ZERO, all others are initialized to SPACES).
  11. The following example may help your understanding of how the "INITIALIZE" statement works. The sample code makes use of the COBDUMP program to dump the storage that is (or is not) being initialized. See COBDUMP in GnuCOBOL Sample Programs, for a source and cross-reference listing of the COBDUMP program.
    IDENTIFICATION DIVISION.
    PROGRAM-ID. DemoInitialize.
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    01  Item-1.
        05 I1-A VALUE ALL '*'.
           10 FILLER                PIC X(1).
           10 I1-A-1                PIC 9(1) VALUE 9.
        05 I1-B                     USAGE BINARY-CHAR.
        05 I1-C                     PIC A(1) VALUE 'C'.
        05 I1-D                     PIC X/X VALUE 'ZZ'.
        05 I1-E                     OCCURS 2 TIMES PIC 9.
    PROCEDURE DIVISION.
    000-Main.
        DISPLAY "MOVE HIGH-VALUES TO Item-1"
            PERFORM 100-Init-Item-1
            CALL "COBDUMP" USING Item-1
            DISPLAY " "
    
        DISPLAY "INITIALIZE Item-1"
            INITIALIZE Item-1
            CALL "COBDUMP" USING Item-1
            PERFORM 100-Init-Item-1
            DISPLAY " "
    
        DISPLAY "INITIALIZE Item-1 WITH "FILLER""
            MOVE HIGH-VALUES TO Item-1
            INITIALIZE Item-1 WITH "FILLER"
            CALL "COBDUMP" USING Item-1
            PERFORM 100-Init-Item-1
            DISPLAY " "
    
        DISPLAY "INITIALIZE Item-1 ALL TO VALUE"
            MOVE HIGH-VALUES TO Item-1
            INITIALIZE Item-1 ALPHANUMERIC TO VALUE
            CALL "COBDUMP" USING Item-1
            PERFORM 100-Init-Item-1
            DISPLAY " "
    
        DISPLAY "INITIALIZE Item-1 REPLACING NUMERIC BY 1"
            MOVE HIGH-VALUES TO Item-1
            INITIALIZE Item-1 REPLACING NUMERIC BY 1
            CALL "COBDUMP" USING Item-1
            PERFORM 100-Init-Item-1
            DISPLAY " "
    
        STOP RUN
        .
    
    100-Init-Item-1.
        MOVE HIGH-VALUES TO Item-1
        .
    

    When executed, this program produces the following output:

    MOVE HIGH-VALUES TO Item-1
    <-Addr-> Byte <---------------- Hexadecimal ----------------> <---- Char ---->
    ======== ==== =============================================== ================
    00404058    1 FF FF FF FF FF FF FF FF FF                      .........
    
    INITIALIZE Item-1
    <-Addr-> Byte <---------------- Hexadecimal ----------------> <---- Char ---->
    ======== ==== =============================================== ================
    00404058    1 FF 30 00 20 20 2F 20 30 30                      .0.  / 00
    
    INITIALIZE Item-1 WITH "FILLER"
    <-Addr-> Byte <---------------- Hexadecimal ----------------> <---- Char ---->
    ======== ==== =============================================== ================
    00404058    1 20 30 00 20 20 2F 20 30 30                       0.  / 00
    
    INITIALIZE Item-1 ALL TO VALUE
    <-Addr-> Byte <---------------- Hexadecimal ----------------> <---- Char ---->
    ======== ==== =============================================== ================
    00404058    1 2A 2A FF 43 5A 5A 20 FF FF                      **.CZZ ..
    
    INITIALIZE Item-1 REPLACING NUMERIC BY 1
    <-Addr-> Byte <---------------- Hexadecimal ----------------> <---- Char ---->
    ======== ==== =============================================== ================
    00404058    1 FF 31 01 FF FF FF FF 31 31                      .1.....11
    


6.17.23. INITIATE

INITIATE Syntax
=======================================================================

 INITIATE report-name-1
 ~~~~~~~~

=======================================================================
  1. Each <report-name-1> must be the name of a report having an "RD" (see REPORT SECTION) defined for it.
  2. The file in whose "FD" (see File/Sort-Description) a "REPORT <report-name-1>" clause exists must be open for "OUTPUT" or "EXTEND" at the time the "INITIATE" statement is executed. See OPEN, for more information on file open modes.
  3. The "INITIATE" statement will initialize all of the following for each report named on the statement:
  4. No report content will actually presented to the report file as a result of a successful "INITIATE" statement — that will not occur until the first "GENERATE" statement (see GENERATE) is executed.


6.17.24. INSPECT

INSPECT Syntax
=======================================================================

 INSPECT { literal-1            }
 ~~~~~~~ { identifier-1         }
         { function-reference-1 }

  [ TALLYING { identifier-2 FOR { ALL|LEADING|TRAILING { literal-2    } }
    ~~~~~~~~                ~~~ { ~~~ ~~~~~~~ ~~~~~~~~ { identifier-3 } }
                                { CHARACTERS                            }
                                  ~~~~~~~~~~
               [ | { AFTER|BEFORE } INITIAL { literal-3    } | ] }... ]
                 |   ~~~~~ ~~~~~~           { identifier-4 } |

  [ REPLACING { { { ALL|FIRST|LEADING|TRAILING { literal-4    } }
    ~~~~~~~~~   { { ~~~ ~~~~~ ~~~~~~~ ~~~~~~~~ { identifier-5 } }
                { CHARACTERS                                    }
                { ~~~~~~~~~~                                    }

                 BY { [ ALL ] literal-5 }
                 ~~ {   ~~~             }
                    { identifier-6      }

               [ | { AFTER|BEFORE } INITIAL { literal-6    } | ] }... ]
                 |   ~~~~~ ~~~~~~           { identifier-7 } |

  [ CONVERTING { { literal-7    } TO { literal-8    }
    ~~~~~~~~~~   { identifier-8 } ~~ { identifier-9 }

               [ | { AFTER|BEFORE } INITIAL { literal-9     } | ] ]
                 |   ~~~~~ ~~~~~~           { identifier-10 } |

=======================================================================
  1. The reserved word "INITIAL" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this words has no effect upon the program.
  2. If a "CONVERTING"
  3. If either the "TALLYING" or "REPLACING" clauses are specified, the "CONVERTING" clause cannot be used.
  4. If both the "TALLYING" and "REPLACING" clauses are specified, they must be specified in the order shown.
  5. All literals and identifiers must be explicitly or implicitly defined as alphanumeric or alphabetic.
  6. If <function-reference-1> is specified, it must be an invocation of an intrinsic function that returns a string result. Additionally, only the "TALLYING" clause may be specified.
  7. If <literal-1> is specified, only the "TALLYING" clause may be specified.
  8. Whichever is specified — <literal-1>, <identifier-1> or <function-reference-1> — that item will be referred to in the discussions that follows as the ’inspect subject’.
  9. The three optional clauses control the operation of this statement as follows:
    1. The "CONVERTING" clause replaces one or more individual characters found in the inspect subject with a different character in much the same manner as is possible with the "TRANSFORM" statement (see TRANSFORM).
    2. The "REPLACING" clause replaces one or more sub strings located in the inspect subject with a different, but equally-sized replacement sub string. If you need to replace a sub string with another of a different length, consider using either the "SUBSTITUTE" intrinsic function (see SUBSTITUTE) or the "SUBSTITUTE-CASE" intrinsic function (see SUBSTITUTE-CASE).
    3. The "TALLYING" clause counts the number of occurrences of one or more strings of characters in the inspect subject.
  10. The optional "INITIAL" clauses may be used to limit the range of characters in the inspect subject that the "CONVERTING", "REPLACING" or "TALLYING" instruction in which they occur will apply. We call this the ’target range’ of the inspect subject. The target range is defined as follows:
    1. If there is no "INITIAL" clause specified, the target range is the entire inspect subject.
    2. Either a "BEFORE" phrase, an "AFTER" phrase or both may be specified. They may be specified in any order.
    3. The starting point of the target range will be the first character following the sub string identified by the "AFTER" specification. The ending point will be the last character immediately preceding the sub string identified by the "BEFORE" specification.
    4. If no "AFTER" is specified, the first character position of the target range will be character position #1 of the inspect subject.
    5. If no "BEFORE" is specified, the last character position of the target range will be the last character position of the inspect subject.
  11. The following points apply to the use of the "TALLYING" clause:
    1. While there will typically be only be a single set of counting instructions on an "INSPECT":
      INSPECT Character-String
          TALLYING C-ABC FOR ALL "ABC"
      

      There could be multiple counting instructions specified:

      INSPECT Character-String
          TALLYING C-ABC FOR ALL "ABC"
                   C-BCDE FOR ALL "BCDE"
      

      When there are multiple instructions, the one specified first will take priority over the one specified second, (and so forth) as the "INSPECT" proceeds forward through the inspect subject, character-by-character.

      With the above example, if the inspect subject were "--ABCDEF----BCDEF--", the final result of the counting would be that C-ABC would be incremented by 1 while C-BCDE would be incremented only once; although the human eye clearly sees two "BCDE" sequences, the "INSPECT ... TALLYING" would only "see" the second — the first would have been processed by the first (higher-priority) counting instruction.

    2. Each set of counting instructions contains the following information:
      1. A target range, specified by the presence of an "AFTER INITIAL" and/or "BEFORE INITIAL" clause; the rules for specifying target ranges were covered previously.
      2. A Target Sub string — this is a sequence of characters to be located somewhere in the inspect subject and counted. Target sub strings may be defined as a literal value (figurative constants are allowed) or by the contents of an identifier. If the target sub string is specified as a figurative constant, it will be assumed to have a length of one (1) character. The keywords before the literal or identifier control how many target sub strings could be identified from that replacement instruction, as follows:

        "ALL" — identifies every possible target sub string that occurs within the target range. There are three occurrences of "ALL 'XX'" found in "aXXabbXXccXXdd".

        "LEADING" — identifies only an occurrence of the target sub string found either at the first character position of the target range or immediately following a previously-found occurrence. There are no occurrences of "LEADING 'XX'" found in "aXXabbXXccXXdd", but there is one occurrence of "LEADING 'a'" (the first character).

        "TRAILING" — identifies only an occurrence of the target sub string found either at the very end of the target range or toward the end, followed by nothing but other occurrences. There are no occurrences of "LEADING 'XX'" found in "aXXabbXXccXXdd", but there are two occurrences of "TRAILING 'd'".

        The "CHARACTERS" option will match any one single character, regardless of what that character is.

    3. <identifier-2> will be incremented by 1 each time the target sub string is found within the target range of the inspect subject. The "INSPECT" statement will not zero-out <identifier-2> at the start of execution of the "INSPECT" — it is the programmer’s responsibility to ensure that all <identifier-2> data items are properly initialized to the desired starting values prior to execution of the "INSPECT".
  12. The following points apply to the use of the "REPLACING" clause:
    1. While there will typically be only be a single set of replacement instructions on an "INSPECT":
      INSPECT Character-String
          REPLACING ALL "ABC" BY "DEF"
      

      There could be multiple replacement instructions:

      INSPECT Character-String
          REPLACING ALL "ABC" BY "DEF"
                    ALL "BCDE" BY "WXYZ"
      

      When there are multiple replacement instructions, the one specified first will take priority over the one specified second, (and so forth) as the "INSPECT" proceeds forward through the inspect subject, character-by-character.

      With the above example, if the inspect subject were "--ABCDEF----BCDEF--", the final result of the replacement would be "--DEFDEF----WXYZF--".

    2. Each set of replacement instructions contains the following information:
      1. A target range, specified by the presence of an "AFTER INITIAL" and/or "BEFORE INITIAL" clause; the rules for specifying target ranges were covered previously.
      2. A Target Sub string — this is a sequence of characters to be located somewhere in the inspect subject and subsequently replaced with a new value. Target sub strings, which are specified before the "BY" keyword, may be defined as a literal value (figurative constants are allowed) or by the contents of an identifier. If the target sub string is specified as a figurative constant, it will be assumed to have a length of one (1) character. The keywords before the literal or identifier control how many target sub strings could be identified from that replacement instruction, as follows:

        "ALL" — identifies every possible target sub string that occurs within the target range. There are three occurrences of "ALL 'XX'" found in "aXXabbXXccXXdd".

        "FIRST" — the first occurrence of the target sub string found within the target range. The "FIRST 'XX'" found in "aXXabbXXccXXdd" would be the one found between the "a" and "b" characters.

        "LEADING" — an occurrence of the target sub string found either at the first character position of the target range or immediately following a previously-found occurrence. There are no occurrences of "LEADING 'XX'" found in "aXXabbXXccXXdd", but there is one occurrence of "LEADING 'a'" (the first character).

        "TRAILING" — an occurrence of the target sub string found either at the very end of the target range or toward the end, followed by nothing but other occurrences. There are no occurrences of "LEADING 'XX'" found in "aXXabbXXccXXdd", but there are two occurrences of "TRAILING 'd'".

        The "CHARACTERS" option will match any one single character. When you use this option, the replacement sub string (see the next item) must be exactly one character in length.

      3. A Replacement Sub string — this is the sequence of characters that should replace the target sub string. Replacement sub strings are specified after the "BY" keyword. They too may be specified as a literal, either with or without an "ALL" prefix (again, figurative constants are allowed) or the value of an identifier. If a figurative constant is coded, the "ALL" keyword will be assumed, even if it wasn’t specified. Literals without "ALL" will either be truncated or padded with spaces on the right to match the length of the target sub string. Literals with "ALL" or figurative constants will be repeated as necessary to match the length of the target sub string. Identifiers specified as replacement sub strings must be defined with a length equal to that of the target sub string.
  13. When both "REPLACING" and "TALLYING" are specified:
    1. The "INSPECT" statement will make a single pass through the sequence of characters comprising the inspect subject. As the pointer to the current inspect target character reaches a point where it falls within the explicit or implicit target ranges specified on the operational instructions of the two clauses, the actions specified by those instructions will become eligible to be taken. As the character pointer reaches a point where it falls past the end of target ranges, the instructions belonging to those target ranges will become disabled.
    2. At any point in time, there may well be multiple"REPLACING" and/or "TALLYING" operational instructions active. Only one of the "TALLYING" and one of the "REPLACING" instructions (if any) can be executed for any one character pointer position. In each case, it will be the first of the instructions in each category that produces a match with it’s target string specification.
    3. When both a "TALLYING" and a "REPLACING" instruction have been selected for execution, the "TALLYING" instruction will be executed first. This guarantees that "TALLYING" will compute occurrences based upon the initial value of the inspect subject before any replacements occur.
  14. The following points apply to the use of the "CONVERTING" clause:
    1. A "CONVERTING" clause performs a series of single-character substitutions against a data item in much the same manner as is possible with the "TRANSFORM" statement (see TRANSFORM).
    2. Unlike the "TALLYING" and "REPLACING" clauses, both of which may have multiple operations specified, there may be only one "CONVERTING" operation per "INSPECT".
    3. If the length of <literal-7> or <identifier-8> (the "from" string) exceeds the length of <literal-8> or <identifier-9> (the "to" string), then the "to" string will be assumed to be padded to the right with enough spaces to make it the same length as the "from" string.
    4. If the length of the "from" string is less than the length of the "to" string, then the "to" string will be truncated to the length of the "from" string.
    5. Each character, in turn, within the "from" string will be searched for in the target range of the inspect subject. Each located occurrence will be replaced by the corresponding character of the "to" string.


6.17.25. MERGE

MERGE Syntax
=======================================================================

 MERGE sort-file-1
 ~~~~~
    { ON { ASCENDING  } KEY identifier-1... }...
         { ~~~~~~~~~  }
         { DESCENDING }
           ~~~~~~~~~~
    [ WITH DUPLICATES IN ORDER ]
           ~~~~~~~~~~
    [ COLLATING SEQUENCE IS alphabet-name-1 ]
      ~~~~~~~~~
      USING file-name-1 file-name-2...
      ~~~~~
    { OUTPUT PROCEDURE IS procedure-name-1    }
    { ~~~~~~ ~~~~~~~~~                        }
    {       [ THRU|THROUGH procedure-name-2 ] }
    {         ~~~~ ~~~~~~~                    }
    { GIVING file-name-3...                   }
    { ~~~~~~                                  }

The "DUPLICATES"


=======================================================================
  1. The reserved words "IN", "IS", "KEY", "ON", "ORDER", "SEQUENCE" and "WITH" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved words "THRU" and "THROUGH" are interchangeable.
  3. GnuCOBOL always behaves as if the "WITH DUPLICATES IN ORDER" clause is specified, even if it isn’t.

    While any COBOL implementation’s sort or merge facilities guarantee that records with duplicate key values will be in proper sequence with regard to other records with different key values, they generally make no promises as to the resulting relative sequence of records having duplicate key values with one another.

    Some COBOL implementations provide this optional clause to force their sort and merge facilities to retain duplicate key-value records in their original input sequence, relative to one another.

  4. The <sort-file-1> named on the "MERGE" statement must be defined using a sort description ("SD" (see File/Sort-Description)). This file is referred to in the remainder of this discussion as the "merge work file".
  5. Each <file-name-1>, <file-name-2> and <file-name-3> (if specified) must reference "ORGANIZATION LINE SEQUENTIAL" (see ORGANIZATION LINE SEQUENTIAL) or "ORGANIZATION SEQUENTIAL" (see ORGANIZATION SEQUENTIAL) files. These files must be defined using a file description ("FD" (see File/Sort-Description)).
  6. The <identifier-1> … field(s) must be defined as field(s) within a record of <sort-file-1>.
  7. The record descriptions of <file-name-1>, <file-name-2>, <file-name-3> (if any) and <sort-file-1> are assumed to be identical in layout and size. While the actual data names used for fields in these files’ records may differ, the structure of records, "PICTURE" (see PICTURE) of fields, "USAGE" (see USAGE) of fields, size of fields and location of fields within the records should match field-by-field across all files, at least as far as the "KEY" fields are concerned.
  8. A common programming technique when using the "MERGE" statement is to define the records of all files involved as simple elementary items of the form "01 record-name PIC X(n)." where n is the record size. The only file where records are actually described in detail would then be <sort-file-1>.
  9. The following rules apply to the files named on the "USING" clause:
    1. None of them may be open at the time the "MERGE" is executed.
    2. Each of those files is assumed to be already sorted according to the specifications set forth on the "MERGE" statement’s "KEY"
    3. No two of those files may be referenced on a "SAME RECORD AREA" (see SAME RECORD AREA), "SAME SORT AREA" or "SAME SORT-MERGE AREA" statement.
  10. The merging process is as follows:
    1. As the "MERGE" statement begins execution, the first record in each of the "USING"
    2. As the "MERGE" statement executes, the current record from each of the "USING" files is examined and compared to each other according to the rules set forth by the "KEY" clause and the alphabet (see Alphabet-Name-Clause) specified on the "COLLATING SEQUENCE"
    3. After the merge work file has been populated, the merged data will be written to each <file-name-3> if the "GIVING"
    4. When "GIVING" is specified, none of the <file-name-3> files can be open at the time the "MERGE" statement is executed.
    5. When an output procedure is used, the procedure(s) specified on the "OUTPUT PROCEDURE" clause will be invoked as if by a procedural "PERFORM" (see Procedural PERFORM) statement with no "VARYING", "TIMES" or "UNTIL" options specified. Merged records may be read from the merge work file — one at a time — within the output procedure using the "RETURN" (see RETURN) statement.

      A "GO TO" statement (see GO TO) that transfers control out of the output procedure will terminate the "MERGE" statement but allows the program to continue executing from the point where the "GO TO" statement transferred control to. Once an output procedure has been "aborted" using a "GO TO" it cannot be resumed, and the contents of the merge work file are lost. You may, however, re-execute the "MERGE" statement itself. USING A "GO TO" statement TO PREMATURELY TERMINATE A MERGE, OR RE-STARTING A PREVIOUSLY-CANCELLED MERGE IS NOT CONSIDERED GOOD PROGRAMMING STYLE AND SHOULD BE AVOIDED.

      An output procedure should be terminated in the same way a procedural "PERFORM" statement would be. Usually, this action will be taken once the "RETURN" statement indicates that all records in the merge work file have been processed, but termination could occur at any time — via an "EXIT" statement (see EXIT) — if required.

      Neither a file-based "SORT" statement (see File-Based SORT) nor another "MERGE" statement may be executed within the scope of the procedures comprising the output procedure unless those statements utilize a different sort or merge work file.

    6. Once the output procedure terminates, or the last <file-name-3> file has been populated with merged data, the output phase — and the "MERGE" statement itself — is complete.


6.17.26. MOVE



6.17.26.1. Simple MOVE

Simple MOVE Syntax
=======================================================================

 MOVE { literal-1    } TO identifier-2...
 ~~~~ { identifier-1 } ~~

=======================================================================
  1. The "MOVE" statement will replace the contents of one or more receiving data items (<identifier-2>) with a new value — the one specified by <literal-1> or <identifier-1>.
  2. Only numeric data can be moved to a numeric or numeric-edited <identifier-2>. A "MOVE" involving numeric data will perform any necessary format conversions that might be necessary due to differing "USAGE" (see USAGE) specifications.
  3. The contents of the <identifier-1> data item will not be changed, unless that same data item appears as an <identifier-2>. Note that such situations will cause a warning message to be issued by the compiler, if warning messages are enabled.


6.17.26.2. MOVE CORRESPONDING

MOVE CORRESPONDING Syntax
=======================================================================

 MOVE CORRESPONDING identifier-1 TO identifier-2...
 ~~~~ ~~~~                       ~~

=======================================================================
  1. The reserved word "CORRESPONDING" may be abbreviated as "CORR".
  2. Both <identifier-1> and <identifier-2> must be group items.
  3. See CORRESPONDING, for a discussion of how corresponding matches between two group items are established.
  4. When corresponding matches are established, the effect of a "MOVE CORRESPONDING" on those matches will be as if a series of individual "MOVE"s were done — one for each match.


6.17.27. MULTIPLY



6.17.27.1. MULTIPLY BY

MULTIPLY BY Syntax
=======================================================================

 MULTIPLY { literal-1    } BY { identifier-2
 ~~~~~~~~ { identifier-1 } ~~

      [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ] }...
        ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                          { NEAREST-AWAY-FROM-ZERO }
                          { ~~~~~~~~~~~~~~~~~~~~~~ }
                          { NEAREST-EVEN           }
                          { ~~~~~~~~~~~~           }
                          { NEAREST-TOWARD-ZERO    }
                          { ~~~~~~~~~~~~~~~~~~~    }
                          { PROHIBITED             }
                          { ~~~~~~~~~~             }
                          { TOWARD-GREATER         }
                          { ~~~~~~~~~~~~~~         }
                          { TOWARD-LESSER          }
                          { ~~~~~~~~~~~~~          }
                          { TRUNCATION             }
                            ~~~~~~~~~~
    [ ON SIZE ERROR imperative-statement-1 ]
         ~~~~ ~~~~~
    [ NOT ON SIZE ERROR imperative-statement-2 ]
      ~~~    ~~~~ ~~~~~
 [ END-DIVIDE ]
   ~~~~~~~~~~

=======================================================================
  1. The reserved words "IS" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. Both <identifier-1> and <identifier-2> must be numeric un-edited data items; <literal-1> must be a numeric literal.
  3. The product of <identifier-1> or <literal-1> and each <identifier-2>, in turn, will be computed and moved to each of the <identifier-2> data items, replacing the prior contents.
  4. The value of <identifier-1> is not altered, unless that same data item appears as an <identifier-2>.
  5. The optional "ROUNDED" (see ROUNDED) clause available to each <identifier-2> will control how non-integer results will be saved.
  6. The optional "ON SIZE ERROR" and "NOT ON SIZE ERROR" clauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-2> with an insufficient number of digit positions available to the left of any implied decimal point. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information.


6.17.27.2. MULTIPLY GIVING

MULTIPLY GIVING Syntax
=======================================================================

 MULTIPLY { literal-1    } BY { literal-2    } GIVING { identifier-3
 ~~~~~~~~ { identifier-1 } ~~ { identifier-2 } ~~~~~~

      [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ] }...
        ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                          { NEAREST-AWAY-FROM-ZERO }
                          { ~~~~~~~~~~~~~~~~~~~~~~ }
                          { NEAREST-EVEN           }
                          { ~~~~~~~~~~~~           }
                          { NEAREST-TOWARD-ZERO    }
                          { ~~~~~~~~~~~~~~~~~~~    }
                          { PROHIBITED             }
                          { ~~~~~~~~~~             }
                          { TOWARD-GREATER         }
                          { ~~~~~~~~~~~~~~         }
                          { TOWARD-LESSER          }
                          { ~~~~~~~~~~~~~          }
                          { TRUNCATION             }
                            ~~~~~~~~~~
    [ ON SIZE ERROR imperative-statement-1 ]
         ~~~~ ~~~~~
    [ NOT ON SIZE ERROR imperative-statement-2 ]
      ~~~    ~~~~ ~~~~~
 [ END-DIVIDE ]
   ~~~~~~~~~~

=======================================================================
  1. The reserved words "IS" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. Both <identifier-1> and <identifier-2> must be numeric un-edited data items; <literal-1> and <literal-2> must be numeric literals.
  3. The product of <identifier-1> or <literal-1> and <identifier-2> or <literal-2> will be computed and moved to each of the <identifier-3> data items, replacing their old contents.
  4. Neither the value of <identifier-1> nor <identifier-2> will be altered, unless either appears as an <identifier-3>.
  5. The optional "ROUNDED" (see ROUNDED) clause available to each <identifier-2> will control how non-integer results will be saved.
  6. The optional "ON SIZE ERROR" and "NOT ON SIZE ERROR" clauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-2> with an insufficient number of digit positions available to the left of any implied decimal point. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information.


6.17.28. OPEN

OPEN Syntax
=======================================================================

 OPEN { { INPUT  } [ SHARING WITH { ALL OTHER } ] file-name-1
 ~~~~   { ~~~~~  }   ~~~~~~~      { ~~~       }
        { OUTPUT }                { NO OTHER  }
        { ~~~~~~ }                { ~~        }
        { I-O    }                { READ ONLY }
        { ~~~    }                  ~~~~ ~~~~
        { EXTEND }
          ~~~~~~
      [ { REVERSED           } ] }...
        { ~~~~~~~~           }
        { WITH { NO REWIND } }
        {      { ~~ ~~~~~~ } }
        {      { LOCK      } }
                 ~~~~

The "NO REWIND"


=======================================================================
  1. The reserved words "OTHER" and "WITH" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The "SHARING" and "WITH LOCK" clauses may not both be specified in the same "OPEN" statement.
  3. Any file defined in a GnuCOBOL program must be successfully opened before it or any of it’s record descriptions may be referenced on:

    A "CLOSE" statement (see CLOSE)

    A "DELETE" statement (see DELETE)

    A "READ" statement (see READ)

    A "REWRITE" statement (see REWRITE)

    A "START" statement (see START)

    An "UNLOCK" statement (see UNLOCK)

    A "WRITE" statement (see WRITE)

  4. Any attempt to open a file that is already open will fail with a file status of 41 (see File Status Codes). This is a fatal error that will terminate the program.
  5. Any open failure (including status 41) may be trapped using "DECLARATIVES" (see DECLARATIVES) or an error procedure established using the "CBL_ERROR_PROC" built-in system subroutine (see CBL_ERROR_PROC) built-in subroutine. When either of these trap routines exit, however, the GnuCOBOL runtime system will still terminate the program after your trap logic is executed. Ultimately, you cannot recover from an open failure.
  6. "INPUT"

    You may only read the existing contents of the file — only the "CLOSE", "READ", "START" and "UNLOCK" statements will be allowed. This enforcement takes place at execution time, not compilation time.

    "OUTPUT"

    You may only write new content (which will completely replace any previous file contents) to the file — only the "CLOSE", "UNLOCK" and "WRITE" statements will be allowed. This enforcement takes place at execution time, not compilation time.

    "I-O"

    You may perform any operation you wish against the file — all file I/O statements will be allowed.

    "EXTEND"

    You may only write new content (which will be appended after the previously existing file contents) to the file — only the "CLOSE", "UNLOCK" and "WRITE" statements will be allowed. This enforcement takes place at execution time, not compilation time. You cannot extend an empty file; this will not generate a runtime error, but no output will appear in the file.

  7. The "SHARING"
  8. The "WITH LOCK"


6.17.29. PERFORM



6.17.29.1. Procedural PERFORM

Procedural PERFORM Syntax
=======================================================================

 PERFORM procedure-name-1 [ THRU|THROUGH procedure-name-2 ]
 ~~~~~~~                    ~~~~ ~~~~~~~
    [ { [ WITH TEST { BEFORE } ] { VARYING-Clause                 } } ]
      {        ~~~~ { ~~~~~~ }   { UNTIL conditional-expression-1 } }
      {             { AFTER  }     ~~~~~                            }
      {               ~~~~~                                         }
      { UNTIL EXIT|FOREVER                                          }
      { ~~~~~ ~~~~ ~~~~~~~                                          }
      { { literal-1    } TIMES                                      }
      { { identifier-1 } ~~~~~                                      }

=======================================================================
  1. The reserved word "WITH" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. The reserved words "THRU" and "THROUGH" are interchangeable.
  3. The reserved word and phrase "FOREVER" and "UNTIL EXIT" are interchangeable.
  4. Both <procedure-name-1> and <procedure-name-2> must be procedure division sections or paragraphs defined in the same program as the "PERFORM" statement. If <procedure-name-2> is specified, it must follow <procedure-name-1> in the program’s source code.
  5. The ’perform scope
  6. <literal-1> must be a numeric literal or a reference to a function that returns a numeric value. The value must be an integer greater than zero.
  7. <identifier-1> must be an elementary un-edited numeric data item with an integer value greater than zero.
  8. Without the "UNTIL"
  9. The "FOREVER" option will repeatedly execute the code within the perform scope with no conditions defined for termination of the repetition — it will be up to the programmer to include an "EXIT SECTION" statement (see EXIT) or "EXIT PARAGRAPH" statement within the procedure(s) being performed that will break out of the loop.
  10. The "TIMES" option will repeat the execution of the code within the perform scope a fixed number of times. When the "PERFORM" statement begins execution, an internal repeat counter (not accessible to the programmer) will be set to the value of <literal-1> or the value within <identifier-1>.

    If the counter has a value greater than zero, the statement(s) within the "PERFORM" scope will be executed, after which the counter will be decremented by 1 with each repetition. Once that counter reaches zero, repetition will cease and control will fall into the next statement following the "PERFORM".

    If the <identifier-1> option was used, altering the value of that data item within the perform scope will not affect the repetition count.

  11. The "UNTIL <conditional-expression-1>" option will repeat the code within the perform scope until the specified conditional expression evaluates to a TRUE value.
  12. The optional "WITH TEST"

    The default, if this clause is absent, is "WITH TEST BEFORE".

    This clause may not be coded when the "TIMES" clause is used.

  13. The optional <VARYING-Clause> is a mechanism that creates an advanced loop-management mechanism complete with one or more numeric data items being automatically incremented (or decremented) on each loop iteration as well as the termination control of an "UNTIL" clause. See VARYING, for the details.


6.17.29.2. Inline PERFORM

Inline PERFORM Syntax
=======================================================================

   PERFORM
   ~~~~~~~
    [ { [ WITH TEST { BEFORE } ] { VARYING-Clause                 } } ]
      {        ~~~~ { ~~~~~~ }   { UNTIL conditional-expression-1 } }
      {             { AFTER  }     ~~~~~                            }
      {               ~~~~~                                         }
      { UNTIL EXIT|FOREVER                                          }
      { ~~~~~ ~~~~ ~~~~~~~                                          }
      { { literal-1    } TIMES                                      }
      { { identifier-1 } ~~~~~                                      }

      imperative-statement-1

 [ END-PERFORM ]
   ~~~~~~~~~~~

=======================================================================


6.17.29.3. VARYING

VARYING Syntax
=======================================================================

 VARYING identifier-2 FROM { literal-2    } [ BY { literal-3    } ]
 ~~~~~~~              ~~~~ { identifier-3 }   ~~ { identifier-4 }
         [ UNTIL conditional-expression-1 ]
           ~~~~~
 [ AFTER identifier-5 FROM { literal-4    } [ BY { literal-5    } ]
   ~~~~~              ~~~~ { identifier-6 }   ~~ { identifier-7 }
         [ UNTIL conditional-expression-2 ] ]...
           ~~~~~

=======================================================================
  1. All identifiers used in a <VARYING-Clause> must be elementary, un-edited numeric data items. All literals must be numeric literals.
  2. The following points describe the sequence of events that take place as a result of the "VARYING" portion of the clause:
    1. When the "PERFORM" begins execution, the "FROM" value will be moved to <identifier>.
    2. If the "PERFORM" specifies or implies "WITH TEST BEFORE", <conditional-expression-1> will be evaluated and processing of the "PERFORM" will halt if the expression evaluates to TRUE. If "WITH TEST BEFORE" was not specified or implied, or if the conditional expression evaluated to FALSE, processing proceeds with step (C).
    3. The statements within the perform scope will be executed. If a "GO TO" executed within the perform scope transfers control to a point outside the perform scope, processing of the "PERFORM" will halt.
    4. When the statements within the perform scope terminate the loop iteration, by…
      • …allowing the flow of execution to attempt to fall past the last statement in the perform scope, or…
      • …executing an "EXIT PERFORM CYCLE" statement (see EXIT), or…
      • …executing an "EXIT PARAGRAPH" statement or "EXIT SECTION" statement when there is only one paragraph (or section) in the perform scope ( this option only applies to a procedural "PERFORM")

      Control will return back to the "PERFORM", where — if "WITH TEST AFTER" was specified — <conditional-expression-1> will be evaluated and processing of the "PERFORM" will halt if the expression evaluates to TRUE. If "WITH TEST AFTER" was not specified, or if the conditional expression evaluated to FALSE, processing continues with the next step.

    5. The "BY" value, if any, will be added to <identifier-2>. If no "BY" is specified, <identifier-2> will be unaffected. You are always free to modify the value of <identifier-2> yourself within the perform scope.
    6. Return to step (C).
  3. Most <VARYING-Clause>s have no "AFTER" specified. Those that do, however, are establishing a loop-within-a-loop situation where the process described above in steps (A) through (F) will take place from the "AFTER", and those six processing steps actually replace step (C) of the "VARYING". This "nesting" process can continue indefinitely, with each additional "AFTER".

This is the point where an example should really help you see this at work. Observe the following code which defines a two-dimensional (3 row by 4 column) table and a pair of numeric data items to be used to subscript references to each element of the table:

01  PERFORM-DEMO.
    05 PD-ROW             OCCURS 3 TIMES.
       10 PD-COL          OCCURS 4 TIMES
          15 PD           PIC X(1).
01  PD-Col-No             PIC 9 COMP.
01  PD-Row-No             PIC 9 COMP.

Let’s say the 3x4 "grid" defined by the above structure has these values:

A B C D
E F G H
I J K L

This code will display "ABCDEFGHIJKL" on the console output window:

PERFORM WITH TEST AFTER
        VARYING PD-Row-No FROM 1 BY 1 UNTIL PD-Row-No = 3
          AFTER PD-Col-No FROM 1 BY 1 UNTIL PD-Col-No = 4
    DISPLAY PD (PD-Row-No, PD-Col-No) WITH NO ADVANCING
END-PERFORM

While this code will display "AEIBFJCGKDHL" on the console output window:

PERFORM WITH TEST AFTER
        VARYING PD-Col-No FROM 1 BY 1 UNTIL PD-Col-No = 4
          AFTER PD-Row-No FROM 1 BY 1 UNTIL PD-Row-No = 3
    DISPLAY PD (PD-Row-No, PD-Col-No) WITH NO ADVANCING
END-PERFORM

While we’re looking at sample code, this code displays "ABCEFG":

PERFORM
        VARYING PD-Row-No FROM 1 BY 1 UNTIL PD-Row-No = 3
          AFTER PD-Col-No FROM 1 BY 1 UNTIL PD-Col-No = 4
    DISPLAY PD (PD-Row-No, PD-Col-No) WITH NO ADVANCING
END-PERFORM

By removing the "WITH TEST" clause, the statement is now assuming "WITH TEST BEFORE". Since testing now happens before the "DISPLAY" statement gets executed, when PD-Row-No is 3 and PD-Col-No is 4 the "DISPLAY" statement won’t be executed.

Most COBOL programmers, when using "WITH TEST BEFORE" explicitly or implicitly have developed the habit of using ">" rather than "=" on "UNTIL" clauses. This would make the sample code:

PERFORM
        VARYING PD-Row-No FROM 1 BY 1 UNTIL PD-Row-No > 3
          AFTER PD-Col-No FROM 1 BY 1 UNTIL PD-Col-No > 4
    DISPLAY PD (PD-Row-No, PD-Col-No) WITH NO ADVANCING
END-PERFORM

With this change, "ABCDEFGHIJKL" is once again displayed.



6.17.30. READ



6.17.30.1. Sequential READ

Sequential READ Syntax
=======================================================================

   READ file-name-1 [ { NEXT|PREVIOUS } ] RECORD [ INTO identifier-1 ]
   ~~~~               { ~~~~ ~~~~~~~~ }            ~~~~
    [ { IGNORING LOCK    } ]
      { ~~~~~~~~ ~~~~    }
      { WITH [ NO ] LOCK }
      {        ~~   ~~~~ }
      { WITH KEPT LOCK   }
      {      ~~~~ ~~~~   }
      { WITH IGNORE LOCK }
      {      ~~~~~~ ~~~~ }
      { WITH WAIT        }
             ~~~~
    [ AT END imperative-statement-1 ]
         ~~~
    [ NOT AT END imperative-statement-2 ]
      ~~~    ~~~
 [ END-READ ]
   ~~~~~~~~

=======================================================================
  1. The reserved words "AT", "RECORD" and "WITH" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The <file-name-1> file must have been defined via an "FD" (see File/Sort-Description), not an "SD".
  3. The <file-name-1> file must currently be open for "INPUT" (see File OPEN Modes) or "I-O".
  4. If <file-name-1> is an "ORGANIZATION RELATIVE" (see ORGANIZATION RELATIVE) or "ORGANIZATION INDEXED" (see ORGANIZATION INDEXED) file with an "ACCESS MODE RANDOM", this statement cannot be used.
  5. If <file-name-1> was specified as "ACCESS MODE SEQUENTIAL", this is the only format of the "READ" statement that is available.
  6. If <file-name-1> is an "ORGANIZATION RELATIVE" (see ORGANIZATION RELATIVE) or "ORGANIZATION INDEXED" (see ORGANIZATION INDEXED) file with "ACCESS MODE DYNAMIC", this statement as well as a random "READ" (see Random READ) may be used.
  7. The keywords "NEXT"
  8. The "PREVIOUS" option is available only for "ORGANIZATION INDEXED" files.
  9. When reading any sequential (any organization) or relative file, the "next" direction refers to the physical sequence of records in the file. When reading an indexed file, the "next" and "previous" directions refer to the sequence of primary or alternate record key values in the file’s records, regardless of where the records physically occur within the file.
  10. The minimal statement "READ <file-name-1>" is perfectly legal according to both READ formats. For that reason, when "ACCESS MODE DYNAMIC" has been specified and you want to tell the GnuCOBOL compiler that this minimal statement should be treated as a sequential "READ", you must add either "NEXT" or "PREVIOUS" to the statement (otherwise it will be treated as a random "READ").
  11. A successful sequential READ will retrieve the next available record from <file-name-1>, in either a "next" or "previous" direction from the most-recently-read record, depending upon the use of the "NEXT" or "PREVIOUS" option. The newly-retrieved record data will be saved into the 01-level record structure(s) that immediately follow the file’s "FD". If the optional "INTO"
  12. When an "ORGANIZATION RELATIVE" file has been successfully read, the file’s "RELATIVE KEY" (see ORGANIZATION RELATIVE) field will be automatically populated with the relative record number (ordinal occurrence number) of the record in the file.
  13. The optional "LOCK" options may be used to manually control access to the retrieved record by other programs while this program is running. See Record Locking, to review the various record locking behaviours.
  14. The optional "AT END" clause, if coded, is used to detect and react to the failure of an attempt to retrieve another record from the file due to an end-of-file (i.e. no more records) condition.
  15. The optional "NOT AT END" clause, if coded, will check checking for a file status value of 00. See File Status Codes, for additional information.


6.17.30.2. Random READ

Random READ Syntax
=======================================================================

   READ file-name-1 RECORD [ INTO identifier-1 ]
   ~~~~                      ~~~~
    [ { IGNORING LOCK    } ]
      { ~~~~~~~~ ~~~~    }
      { WITH [ NO ] LOCK }
      {        ~~   ~~~~ }
      { WITH KEPT LOCK   }
      {      ~~~~ ~~~~   }
      { WITH IGNORE LOCK }
      {      ~~~~~~ ~~~~ }
      { WITH WAIT        }
             ~~~~
    [ KEY IS identifier-2 ]
      ~~~
    [ INVALID KEY imperative-statement-1 ]
      ~~~~~~~
    [ NOT INVALID KEY imperative-statement-2 ]
      ~~~ ~~~~~~~
 [ END-READ ]
   ~~~~~~~~

=======================================================================
  1. The reserved words "IS", "KEY" (on the "INVALID" and "NOT INVALID" clauses), "RECORD" and "WITH" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The <file-name-1> file must have been defined via an "FD" (see File/Sort-Description), not an "SD".
  3. The <file-name-1> file must currently be open for "INPUT" (see File OPEN Modes) or "I-O".
  4. If the "ACCESS MODE" of <file-name-1> is "SEQUENTIAL", or the "ORGANIZATION" of the file is any form of sequential, this format of the "READ" statement cannot be used.
  5. If the "ACCESS MODE" of <file-name-1> is "RANDOM", this is the only format of the "READ" statement that is available.
  6. If <file-name-1> is an "ORGANIZATION RELATIVE" (see ORGANIZATION RELATIVE) or "ORGANIZATION INDEXED" (see ORGANIZATION INDEXED) file with "ACCESS MODE DYNAMIC", this statement as well as a sequential "READ" (see Sequential READ) may be used.
  7. The minimal statement "READ <file-name-1>" is perfectly legal according to both READ formats. For that reason, when "ACCESS MODE DYNAMIC" has been specified and you want to tell the GnuCOBOL compiler that this minimal statement should be treated as a random "READ", you must omit the "NEXT" or "PREVIOUS" available to the sequential format of the "READ" statement to ensure the statement will be treated as a random "READ".
  8. The optional "KEY"
    1. …if the file is an "ORGANIZATION RELATIVE" file, the contents of the field declared as the file’s "RELATIVE KEY" will be used to identify a record, otherwise…
    2. …if the file is an "ORGANIZATION INDEXED" file, the contents of the field declared as the file’s "RECORD KEY" will be used to identify a record.
  9. But, if the "KEY" clause is specified, and…
    1. …if the file is an "ORGANIZATION RELATIVE" file, the contents of <identifier-2> will be used as the relative record number of the record to be accessed — <identifier-2> need not be the "RELATIVE KEY" (see ORGANIZATION RELATIVE) field of the file (although it could be if you wish).
    2. …if the file is an "ORGANIZATION INDEXED" file, <identifier-2> must be the "RECORD KEY" (see ORGANIZATION INDEXED) or one of the file’s "ALTERNATE RECORD KEY" fields (if any) — the current contents of that field will identify the record to be accessed. If an alternate record key is used, and that key allows duplicate values, the record accessed will be the first one having that key value.
  10. Once read from the file, the newly-retrieved record data will be saved into the 01-level record structure(s) that immediately follow the file’s "FD". If the optional "INTO"
  11. When an "ORGANIZATION RELATIVE" file has been successfully read, the file’s "RELATIVE KEY" (see ORGANIZATION RELATIVE) field will be automatically populated with the relative record number (ordinal occurrence number) of the record in the file.
  12. The optional "LOCK" options may be used to manually control access to the retrieved record by other programs while this program is running. See Record Locking, to review the various record locking behaviours.
  13. The optional "INVALID KEY" and "NOT INVALID KEY" clauses may be used to detect and react to the failure or success, respectively, by detecting non-zero (typically 23 = key not found = record not found) and 00 file status codes, respectively. See File Status Codes, for additional information.


6.17.31. READY TRACE

READY TRACE Syntax
=======================================================================

 READY TRACE
 ~~~~~ ~~~~~

=======================================================================
  1. In order for this statement to be functional, tracing code must have been generated into the compiled program using either the "-ftrace" switch
  2. Tracing may be turned off at any point by executing the "RESET TRACE" statement (see RESET TRACE).
  3. The


6.17.32. RELEASE

RELEASE Syntax
=======================================================================

 RELEASE record-name-1 [ FROM { literal-1    } ]
 ~~~~~~~                 ~~~~ { identifier-1 }

=======================================================================
  1. This statement is valid only within the "INPUT PROCEDURE" of a file-based "SORT" statement (see File-Based SORT).
  2. The specified <record-name-1> must be a record defined to the sort description ("SD" (see File/Sort-Description)) of the sort work file being processed by the current sort.
  3. The optional "FROM"


6.17.33. RESET TRACE

RESET TRACE Syntax
=======================================================================

 RESET TRACE
 ~~~~~ ~~~~~

=======================================================================
  1. By default, procedure and procedure-and-statement tracing is off as programs begin execution. The "READY TRACE" statement (see READY TRACE) can be used to turn tracing on.
  2. In order for this statement to be functional, tracing code must have been generated into the compiled program using either the "-ftrace" switch
  3. The


6.17.34. RETURN

RETURN Syntax
=======================================================================

   RETURN sort-file-name-1 RECORD
   ~~~~~~
    [ INTO identifier-1 ]
      ~~~~
      AT END imperative-statement-1
         ~~~
    [ NOT AT END imperative-statement-2 ]
      ~~~    ~~~
 [ END-RETURN ]
   ~~~~~~~~~~

=======================================================================
  1. The reserved words "AT" and "RECORD" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The "RETURN" statement is valid only within the "OUTPUT PROCEDURE" of a file-based "SORT" (see File-Based SORT) or a "MERGE" statement (see MERGE) statement.
  3. The <sort-file-name-1> file must be a sort- or merge work file defined with a "SD" (see File/Sort-Description), not an "FD".
  4. A successful "RETURN" will retrieve the next available record from <sort-file-name-1>. The newly-retrieved record data will be saved into the 01-level record structure(s) that immediately follow the file’s SD. If the optional "INTO"
  5. The mandatory "AT END" clause is used to detect and react to the failure of an attempt to retrieve another record from the file due to an end-of-file (i.e. no more records) condition.
  6. The optional "NOT AT END" clause, if coded, will check checking for a file status value of 00. See File Status Codes, for additional information.


6.17.35. REWRITE

REWRITE Syntax
=======================================================================

   REWRITE record-name-1
   ~~~~~~~
      [ FROM { literal-1    } ]
        ~~~~ { identifier-1 }

      [ WITH [ NO ] LOCK ]
               ~~   ~~~~
      [ INVALID KEY imperative-statement-1 ]
        ~~~~~~~
      [ NOT INVALID KEY imperative-statement-2 ]
        ~~~ ~~~~~~~
 [ END-REWRITE ]
   ~~~~~~~~~~~

=======================================================================
  1. The reserved words "KEY" and "WITH" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The <record-name-1> specified on the statement must be defined as an 01-level record subordinate to the File Description ("FD" (see File/Sort-Description)) of a file that is currently open for "I-O" (see File OPEN Modes).
  3. The optional "FROM"
  4. This statement may not be used with "ORGANIZATION LINE SEQUENTIAL" (see ORGANIZATION LINE SEQUENTIAL) files.
  5. Rewriting a record does not cause the contents of the file to be physically updated until the next block of the file is read, a "COMMIT" (see COMMIT) or "UNLOCK" statement (see UNLOCK) is issued or that file is closed.
  6. If the file has "ORGANIZATION SEQUENTIAL" (see ORGANIZATION SEQUENTIAL):
    1. The record to be rewritten will be the one retrieved by the most-recently executed "READ" (see READ) of the file.
    2. If the "FD" of the file contains the "RECORD CONTAINS" or "RECORD IS VARYING" clause, and that clause allows the record size to vary, the size of <record-name-1> cannot be altered.
  7. If the file has "ORGANIZATION RELATIVE" (see ORGANIZATION RELATIVE) or "ORGANIZATION INDEXED" (see ORGANIZATION INDEXED):
    1. If the file has "ACCESS MODE SEQUENTIAL", the record to be rewritten will be the one retrieved by the most-recently executed "READ" of the file. If the file has "ACCESS MODE RANDOM" or "ACCESS MODE DYNAMIC", no "READ" is required before a record may be rewritten — the "RELATIVE KEY" or "RECORD KEY" definition for the file, respectively, will specify the record to be updated.
    2. If the "FD" of the file contains the "RECORD CONTAINS" or "RECORD IS VARYING" clause, and that clause allows the record size to vary, the size can be altered.
  8. The optional "LOCK" options may be used to manually control access to the re-written record by other programs while this program is running. See Record Locking, to review the various record locking behaviours.
  9. The optional "INVALID KEY" and "NOT INVALID KEY" clauses may be used to detect and react to the failure or success, respectively, by detecting non-zero (typically 23 = key not found = record not found) and 00 file status codes, respectively. See File Status Codes, for additional information.


6.17.36. ROLLBACK

ROLLBACK Syntax
=======================================================================

 ROLLBACK
 ~~~~~~~~

=======================================================================
  1. All locks currently being held for all open files will be released.
  2. See Record Locking, to review the various record locking behaviours.


6.17.37. SEARCH

SEARCH Syntax
=======================================================================

   SEARCH table-name-1
   ~~~~~~
      [ VARYING index-name-1 ]
        ~~~~~~~
      [ AT END imperative-statement-1 ]
           ~~~
      { WHEN conditional-expression-1 imperative-statement-2 }...
        ~~~~
 [ END-SEARCH ]
   ~~~~~~~~~~

=======================================================================
  1. The reserved word "AT" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. The searching process will be controlled through a ’Search Index
  3. At the time the "SEARCH" statement is executed, the current value of the search index data item will define the starting position in the table where the searching process will begin. Typically, one initializes that index to a value of 1 before starting the "SEARCH" via "SET <search-index> TO 1".
  4. Each of the <conditional-expression-n>s on the "WHEN" clause(s) should involve a data element within the table, subscripted using the search index.
  5. The searching process is as follows:
    1. Each <conditional-expression-n> will be evaluated, in turn, until either one evaluates to a value of TRUE or all have evaluated to FALSE.
    2. The <imperative-statement-n> (see Imperative Statement) specified on the "WHEN" clause whose <conditional-expression-n> evaluated to TRUE will be executed; after that, the search will be considered complete and control will fall into the first executable statement following the "SEARCH".
    3. If all <conditional-expression-n>s evaluated to FALSE:
      • The search index will be incremented by 1
      • If the search index now has a value greater than the number of entries in the table, the search is considered to have failed and the <imperative-statement-1> on the optional "AT END"
      • If the search index now has a value less than or equal to the number of entries in the table, search processing returns back to step (A).


6.17.38. SEARCH ALL

SEARCH ALL Syntax
=======================================================================

   SEARCH ALL table-name-1
   ~~~~~~ ~~~
      [ AT END imperative-statement-1 ]
           ~~~
        WHEN conditional-expression-1 imperative-statement-2
        ~~~~
 [ END-SEARCH ]
   ~~~~~~~~~~

=======================================================================
  1. The reserved word "AT" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. To be eligible for searching via "SEARCH ALL":
    1. The "OCCURS" clause of <table-name-1> must contain the following elements:
      • An "INDEXED BY"
      • An "ASCENDING KEY"
    2. Just because the table has one or more "KEY" clauses doesn’t mean the data is actually in that sequence in the table — the actual sequence of the data must agree with the KEY clause(s)! A table-based "SORT" (see Table SORT) can prove very useful in this regard.
    3. No two records in the table may have the same "KEY" field values. If the table has multiple "KEY" definitions, then no two records in the table may have the same combination of "KEY" field values.
  3. If rule (A) is violated, the compiler will reject the "SEARCH ALL". If rules (B) and/or (C) are violated, there will be no message issued by the compiler, but the run-time results of a "SEARCH ALL" against the table will probably be incorrect.
  4. The <conditional-expression-1> should involve the "KEY" field(s), using the search index (the table’s "INDEXED BY" index name) as a subscript.
  5. The function of the single, mandatory, "WHEN"
  6. The internal processing of the SEARCH ALL statement begins by setting internal "first" and "last" pointers to the 1st and last entry locations of the table. Processing then proceeds as follows:
    1. The entry half-way between "first" and "last" is identified. We’ll call this the "current" entry, and will set its table entry location into <index-name-1>.
    2. The <conditional-expression-1> is evaluated. This comparison of the key(s) against the target literal/identifier values will have one of three possible outcomes:
      • If the key(s) and value(s) match, <imperative-statement-2> (see Imperative Statement) is executed, after which control falls through into the next statement following the "SEARCH ALL".
      • If the key(s) are LESS THAN the value(s), then the table entry being searched for can only occur in the "current" to "last" range of the table, so a new "first" pointer value is set (it will be set to the "current" pointer).
      • If the key(s) are GREATER THAN the value(s), then the table entry being searched for can only occur in the "first" to "current" range of the table, so a new "last" pointer value is set (it will be set to the "current" pointer).
    3. If the new "first" and "last" pointers are different than the old "first" and "last" pointers, there’s more left to be searched, so return to step (A) and continue.
    4. If the new "first" and "last" pointers are the same as the old "first" and "last" pointers, the table has been exhausted and the entry being searched for cannot be found; <imperative-statement-1> is executed, after which control falls through into the next statement following the "SEARCH ALL". If there is no "AT END" clause coded, control simply falls into the next statement following the "SEARCH ALL".
  7. The net effect of the above algorithm is that only a fraction of the number of elements in the table need ever be tested in order to decide whether or not a particular entry exists. This is because the half the remaining entries in the table are discarded each time an entry is checked.
  8. Computer scientists will compare the two techniques implemented by the "SEARCH" and "SEARCH ALL" statements as follows:
  9. When searching a table with "n" entries, a sequential search will need an average of n/2 tests and a worst case of n tests in order to find an entry and n tests to identify that an entry doesn’t exist.
  10. When searching a table with "n" entries, a binary search will need a worst-case of log2(n) tests in order to find an entry and log2(n) tests to identify that an entry doesn’t exist (n = the number of entries in the table), where "log2" is the base-2 logarithm function.

Here’s a more practical view of the difference. Let’s say that a table has 1,000 entries in it. With a sequential search, on average, you’ll have to check 500 of them to find an entry and you’ll have to look at all 1,000 of them to find that an entry doesn’t exist.

With a binary search, express the number of entries as a binary number (1,000 = 1111101000), count the number of digits in the result (which is, essentially, what a logarithm is, when rounded up to the next integer — the number of digits a decimal number would have if expressed in the logarithm’s number base). In this case, we end up with 10 — THAT is the worst-case number of tests required to find an entry or to identify that it doesn’t exist. That’s quite an improvement!



6.17.39. SET



6.17.39.1. SET ENVIRONMENT

SET ENVIRONMENT Syntax
=======================================================================

 SET ENVIRONMENT { literal-1    } TO { literal-2    }
 ~~~ ~~~~~~~~~~~ { identifier-1 } ~~ { identifier-2 }

=======================================================================
  1. The value of <literal-1> or <identifier-1> specifies the name of the environment variable to set.
  2. The value of <literal-2> or <identifier-2> specifies the value to be assigned to the environment variable.
  3. Environment variables created or changed from within GnuCOBOL programs will be available to any sub-shell processes spawned by that program (i.e. CALL "SYSTEM") but will not be known to the shell or console window that started the GnuCOBOL program.

This is a much simpler and more readable means of setting environment variables than by using the "DISPLAY UPON ENVIRONMENT-NAME" statement (see DISPLAY UPON ENVIRONMENT-NAME). For example, these two code sequences produce identical results:

DISPLAY "VARNAME" UPON ENVIRONMENT-NAME
DISPLAY "VALUE" UPON ENVIRONMENT-VALUE

SET ENVIRONMENT "VARNAME" TO "VALUE"


6.17.39.2. SET Program-Pointer

SET Program-Pointer Syntax
=======================================================================

 SET program-pointer-1 TO ENTRY { literal-1    }
 ~~~                   ~~ ~~~~~ { identifier-1 }

=======================================================================
  1. If you have used other versions of COBOL before (particularly mainframe implementations), you’ve possibly seen subroutine calls made passing a procedure name as an argument — that is not possible in GnuCOBOL; instead, you need to know how to use this form of the "SET" statement.
  2. The "USAGE" (see USAGE) of <program-pointer-1> must be "PROGRAM-POINTER".
  3. The <literal-1> or <identifier-1> value specified must name a primary entry-point name ("PROGRAM-ID" of a subroutine or "FUNCTION-ID" of a user-defined function) or an alternate entry-point defined via an "ENTRY" statement within a subprogram.
  4. Once the address of a procedure division code area has been acquired in this way, the address could be passed to a subroutine (usually written in C) for whatever use it needs it for. For examples of "PROGRAM-POINTER"s at work, see the discussions of the "CBL_ERROR_PROC" built-in system subroutine (see CBL_ERROR_PROC) and "CBL_EXIT_PROC" built-in system subroutine (see CBL_EXIT_PROC).


6.17.39.3. SET ADDRESS

SET ADDRESS Syntax
=======================================================================

 SET [ ADDRESS OF ] { pointer-name-1 }...
 ~~~   ~~~~~~~ ~~   { identifier-1   }

     TO [ ADDRESS OF ]  { pointer-name-2 }
     ~~   ~~~~~~~ ~~    { identifier-2   }

=======================================================================
  1. When the "ADDRESS OF"
  2. When the "ADDRESS OF" clause is used after the "TO", this statement will be identifying the address of <identifier-2> as the address to be assigned to <identifier-1> or stored in <pointer-name-1>.
  3. If the "ADDRESS OF" clause is absent after the "TO", the contents of <pointer-name-2> will serve as the address to be assigned.


6.17.39.4. SET Index

SET Index Syntax
=======================================================================

 SET index-name-1 TO { literal-1    }
 ~~~              ~~ { identifier-2 }

=======================================================================
  1. Either the "USAGE" (see USAGE) of <index-name-1> should be "INDEX", or <index-name-1> must be identified in a table "INDEXED BY" clause.


6.17.39.5. SET UP/DOWN

SET UP/DOWN Syntax
=======================================================================

 SET identifier-1 { UP   } BY [ LENGTH OF ] { literal-1    }
 ~~~              { ~~   } ~~   ~~~~~~ ~~   { identifier-2 }
                  { DOWN }
                    ~~~~

=======================================================================
  1. The "USAGE" (see USAGE) of <identifier-1> must be "INDEX", "POINTER" or "PROGRAM-POINTER".
  2. The typical usage when <identifier-1> is a "USAGE INDEX" data item is to increment it’s value "UP" or "DOWN" by 1, since an index is usually being used to sequentially walk through the elements of a table.


6.17.39.6. SET Condition Name

SET Condition Name Syntax
=======================================================================

 SET condition-name-1... TO { TRUE  }
 ~~~                     ~~ { ~~~~  }
                            { FALSE }
                              ~~~~~

=======================================================================
  1. By setting the specified <condition-name-1>(s) to a TRUE or FALSE value, you will actually be assigning a value to the parent data item(s) to which the condition name data item(s) is(are) subordinate to.
  2. When specifying "TRUE", the value assigned to each parent data item will be the first value specified on the condition name’s "VALUE" clause.
  3. When specifying "FALSE", the value assigned to each parent data item will be the value specified for the "FALSE" clause of the condition name’s definition; if any <condition-name-1> occurrence lacks a "FALSE" clause, the "SET" statement will be rejected by the compiler.


6.17.39.7. SET Switch

SET Switch Syntax
=======================================================================

 SET mnemonic-name-1... TO { ON  }
 ~~~                    ~~ { ~~  }
                           { OFF }
                             ~~~

=======================================================================
  1. Switches are defined using the "SPECIAL-NAMES" (see SPECIAL-NAMES) paragraph.
  2. Switches may be tested via the "IF" statement (see IF) and a Switch-Status Condition. See Switch-Status Conditions, for more information.


6.17.39.8. SET ATTRIBUTE

SET ATTRIBUTE Syntax
=======================================================================

 SET identifier-1 ATTRIBUTE { { BELL          } { ON  }...
 ~~~              ~~~~~~~~~   { ~~~~          } { ~~  }
                              { BLINK         } { OFF }
                              { ~~~~~         }   ~~~
                              { HIGHLIGHT     }
                              { ~~~~~~~~~     }
                              { LEFTLINE      }
                              { ~~~~~~~~      }
                              { LOWLIGHT      }
                              { ~~~~~~~~      }
                              { OVERLINE      }
                              { ~~~~~~~~      }
                              { REVERSE-VIDEO }
                              { ~~~~~~~~~~~~~ }
                              { UNDERLINE     }
                                ~~~~~~~~~

=======================================================================
  1. When making an attribute change to <identifier-1>, the change will not become visible on the screen until the screen section data item containing <identifier-1> is next accepted (if <identifier-1> is an input field) or is next displayed (if <identifier-1> is not an input field).
  2. The attributes shown in the syntax diagram are the only ones that may be altered by this statement. See Data Description Clauses, for information on their usage.


6.17.40. SORT



6.17.40.1. File-Based SORT

File-Based SORT Syntax
=======================================================================

 SORT sort-file-1
 ~~~~
    { ON { ASCENDING  } KEY identifier-1... }...
         { ~~~~~~~~~  }
         { DESCENDING }
           ~~~~~~~~~~
    [ WITH DUPLICATES IN ORDER ]
           ~~~~~~~~~~
    [ COLLATING SEQUENCE IS alphabet-name-1 ]
      ~~~~~~~~~

    { INPUT PROCEDURE IS procedure-name-1      }
    { ~~~~~~ ~~~~~~~~~                         }
    {       [ THRU|THROUGH procedure-name-2 ]  }
    {         ~~~~ ~~~~~~~                     }
    { USING file-name-1...                     }
      ~~~~~
    { OUTPUT PROCEDURE IS procedure-name-3     }
    { ~~~~~~ ~~~~~~~~~                         }
    {       [ THRU|THROUGH procedure-name-4 ]  }
    {         ~~~~ ~~~~~~~                     }
    { GIVING file-name-3...                    }
      ~~~~~~

The "DUPLICATES"


=======================================================================
  1. The reserved words "IN", "IS", "KEY", "ON", "ORDER", "SEQUENCE" and "WITH" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved words "THRU" and "THROUGH" are interchangeable.
  3. GnuCOBOL always behaves as if the "WITH DUPLICATES IN ORDER" clause is specified, even if it isn’t.

    While any COBOL implementation’s sort or merge facilities guarantee that records with duplicate key values will be in proper sequence with regard to other records with different key values, they generally make no promises as to the resulting relative sequence of records having duplicate key values with one another.

    Some COBOL implementations provide this optional clause to force their sort and merge facilities to retain duplicate key-value records in their original input sequence, relative to one another.

  4. The <sort-file-1> named on the "SORT" statement must be defined using a sort description ("SD" (see File/Sort-Description)). This file is referred to in the remainder of this discussion as the "sort work file".
  5. If specified, <file-name-1> and <file-name-2> must reference "ORGANIZATION LINE SEQUENTIAL" (see ORGANIZATION LINE SEQUENTIAL) or "ORGANIZATION SEQUENTIAL" (see ORGANIZATION SEQUENTIAL) files. These files must be defined using a file description ("FD" (see File/Sort-Description)). The same file(s) may be used for <file-name-1> and <file-name-2>.
  6. The <identifier-1> … field(s) must be defined as field(s) within a record of <sort-file-1>.
  7. A sort work file is never opened or closed.
  8. The sorting process works in three stages — the Input Stage, the Sort Stage and the Output Stage.
  9. The following points pertain to the Input Stage:
    1. The data to be sorted is loaded into the sort work file either by copying the entire contents of the file(s) named on the "USING" clause (done automatically by the sort) or by utilizing an input procedure.
    2. When "USING"
    3. When an input procedure is used, the procedure(s) specified on the "INPUT PROCEDURE"

      A "GO TO" statement (see GO TO) that transfers control out of the input procedure will terminate the "SORT" statement but allows the program to continue executing from the point where the "GO TO" statement transferred control to. Once an input procedure has been "aborted" using a "GO TO" it cannot be resumed, and the contents of the sort work file are lost. You may, however, re-execute the "SORT" statement itself. USING A "GO TO" statement TO PREMATURELY TERMINATE A SORT, OR RE-STARTING A PREVIOUSLY-CANCELLED SORT IS NOT CONSIDERED GOOD PROGRAMMING STYLE AND SHOULD BE AVOIDED.

      An input procedure should be terminated in the same way a procedural "PERFORM" statement would be.

      Neither a another file-based "SORT" statement nor a "MERGE" statement may be executed within the input procedure unless those statements utilize a different sort or merge work file.

    4. Once the input procedure terminates, the input phase is complete.
    5. As data is loaded into the sort work file, it is actually being buffered in dynamically-allocated memory. Only if the amount of data to be sorted exceeds the amount of available sort memory (128 MB) will actual disk files be allocated and utilized. There is a
  10. The following points pertain to the Sort Stage:
    1. The sort will take place by arranging the data records in the sequence defined by the "KEY" specification(s) on the "SORT" statement according to the "COLLATING SEQUENCE" specified on the "SORT" (if any) or — if none was defined — the "PROGRAM COLLATING SEQUENCE" (see OBJECT-COMPUTER). Keys may be any supported data type and "USAGE" (see USAGE) except for level-78 or level-88 data items.
    2. For example, let’s assume we’re sorting a series of financial transactions. The SORT statement might look like this:
      SORT Sort-File
          ASCENDING  KEY Transaction-Date
          ASCENDING  KEY Account-Number
          DESCENDING KEY Transaction-Amount
      

      The effect of this statement will be to sort all transactions into ascending order of the date the transaction took place (oldest first, newest last). Unless the business running this program is going out of business, there are most-likely many transactions for any given date. Therefore, within each grouping of transactions all with the same date, transactions will be sub-sorted into ascending sequence of the account number the transactions apply to. Since it’s quite possible there might be multiple transactions for an account on any given date, a third level sub-sort will arrange all transactions for the same account on the same date into descending sequence of the actual amount of the transaction (largest first, smallest last). If two or more transactions of $100.00 were recorded for account #12345 on the 31st of August 2009, those transactions will be retained in the order in which they were loaded into the sort work file.

    3. Should disk work files be necessary due to the amount of data being sorted, they will be automatically allocated to disk in a folder defined by the
  11. The following points pertain to the Output Stage:
    1. Once the sort stage is complete, a copy of the sorted data will be written to each <file-name-2> if the "GIVING"
    2. When an output procedure is used, the procedure(s) specified on the "OUTPUT PROCEDURE"

      A "GO TO" statement (see GO TO) that transfers control out of the output procedure will terminate the "SORT" statement but allows the program to continue executing from the point where the "GO TO" statement transferred control to. Once an output procedure has been "aborted" using a "GO TO" it cannot be resumed, and the contents of the sort work file are lost. You may, however, re-execute the "SORT" statement itself. USING A "GO TO" statement TO PREMATURELY TERMINATE A SORT, OR RE-STARTING A PREVIOUSLY-CANCELLED SORT IS NOT CONSIDERED GOOD PROGRAMMING STYLE AND SHOULD BE AVOIDED.

      An output procedure should be terminated in the same way a procedural "PERFORM" statement would be.

      Neither a another file-based "SORT" statement nor a "MERGE" statement may be executed within the output procedure unless those statements utilize a different sort or merge work file.

    3. Once the output procedure terminates, the sort is complete.


6.17.40.2. Table SORT

Table SORT Syntax
=======================================================================

 SORT table-name-1
 ~~~~
    { ON { ASCENDING  } KEY identifier-1... }...
         { ~~~~~~~~~  }
         { DESCENDING }
           ~~~~~~~~~~
    [ WITH DUPLICATES IN ORDER ]
           ~~~~~~~~~~
    [ COLLATING SEQUENCE IS alphabet-name-1 ]
      ~~~~~~~~~

The "DUPLICATES"


=======================================================================
  1. The reserved words "IN", "IS", "KEY", "ON", "ORDER", "SEQUENCE" and "WITH" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. GnuCOBOL always behaves as if the "WITH DUPLICATES IN ORDER" clause is specified, even if it isn’t.

    While any COBOL implementation’s sort or merge facilities guarantee that records with duplicate key values will be in proper sequence with regard to other records with different key values, they generally make no promises as to the resulting relative sequence of records having duplicate key values with one another.

    Some COBOL implementations provide this optional clause to force their sort and merge facilities to retain duplicate key-value records in their original input sequence, relative to one another.

  3. The <table-name-1> data item must be a table defined in any data division section except the report or screen sections.
  4. The data within <table-name-1> will be sorted in-place (i.e. no sort file is required).
  5. The sort will take place by rearranging the data in <table-name-1> into the sequence defined by the "KEY" specification(s) on the "SORT" statement, according to the "COLLATING SEQUENCE" specified on the "SORT" (if any) or — if none was defined — the "PROGRAM COLLATING SEQUENCE" (see OBJECT-COMPUTER). Keys may be any supported data type and "USAGE" (see USAGE) except for level-78 or level-88 data items.
  6. If you are sorting <table-name-1> for the purpose of preparing the table for use with a "SEARCH ALL" statement (see SEARCH ALL), care must be taken that the "KEY" specifications on the "SORT" agree with those in the table’s definition.
  7. Although the specification of one or more KEY clauses is optional, currently, a table sort with no "KEY" specification(s) made on the "SORT" statement is unsupported by GnuCOBOL and will be rejected by the compiler.


6.17.41. START

START Syntax
=======================================================================

   START file-name-1
   ~~~~~
     [ { FIRST                                                    } ]
       { ~~~~~                                                    }
       { LAST                                                     }
       { ~~~~                                                     }
       { KEY { IS EQUAL TO | IS = | EQUALS         } identifier-1 }
             {    ~~~~~             ~~~~~~         }
             { IS GREATER THAN | IS >              }
             {    ~~~~~~~                          }
             { IS GREATER THAN OR EQUAL TO | IS >= }
             {    ~~~~~~~      ~~ ~~~~~            }
             { IS NOT LESS THAN                    }
             {    ~~~ ~~~~                         }
             { IS LESS THAN | IS <                 }
             {    ~~~~                             }
             { IS LESS THAN OR EQUAL TO | IS <=    }
             {    ~~~~      ~~ ~~~~~               }
             { IS NOT GREATER THAN                 }
                  ~~~ ~~~~~~~
    [ INVALID KEY imperative-statement-1 ]
      ~~~~~~~
    [ NOT INVALID KEY imperative-statement-2 ]
      ~~~ ~~~~~~~
 [ END-START ]
   ~~~~~~~~~

=======================================================================
  1. The reserved words "IS", "KEY", "THAN" and "TO" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. To use this statement, <file-name-1> must be an "ORGANIZATION RELATIVE" (see ORGANIZATION RELATIVE) or "ORGANIZATION INDEXED" (see ORGANIZATION INDEXED) file that must have been defined with an "ACCESS MODE DYNAMIC" or "ACCESS MODE SEQUENTIAL" in its "SELECT" statement (see SELECT).
  3. At the time this statement is executed, <file-name-1> must be open in either "INPUT" or "I-O" (see File OPEN Modes) mode.
  4. If <file-name-1> is a relative file, <identifier-1> must be the defined "RELATIVE KEY" of the file.
  5. If <file-name-1> is an indexed file, <identifier-1> must be the defined "RECORD KEY" of the file or any of the "ALTERNATE RECORD KEY" fields for the file.
  6. If no "FIRST", "LAST" or "KEY" clause is specified, "KEY IS EQUAL TO xxx" will be assumed, where "xxx" is the defined "RELATIVE KEY" of (if <file-name-1> is a relative file) or the defined "RECORD KEY" (if <file-name-1> is an indexed file).
  7. After successful execution of a "START" statement, the internal logical record pointer into the <file-name-1> data will be positioned to the record which satisfied the actual or implied "FIRST", "LAST" or "KEY" clause specification, as follows:
    1. If "FIRST" was specified, the logical record pointer will point to the first record in the file.
    2. If "LAST" was specified, the logical record pointer will point to the last record in the file.
    3. If "KEY" was specified or implied, the logical record pointer will be specified to the first record satisfying the relation condition; to identify this record, the file’s contents are searched in a first-to-last (in sequence of the key implied by the "KEY" clause), provided the relation is "EQUAL TO", "GREATER THAN" or "GREATER THAN OR EQUAL TO" (or any of their syntactical equivalents).
    4. If "KEY" was specified or implied, the logical record pointer will be specified to the last record satisfying the relation condition; to identify this record, the file’s contents are searched in a last-to-first (in sequence of the key implied by the "KEY" clause), provided the relation is "LESS THAN", "LESS THAN OR EQUAL TO" or "NOT GREATER THAN" (or any of their syntactical equivalents).

    The next sequential "READ" statement will read the record that is pointed to by the logical record pointer.

  8. The optional "INVALID KEY" and "NOT INVALID KEY" clauses may be used to detect and react to the failure or success, respectively, by detecting non-zero (typically 23 = key not found = record not found) and 00 file status codes, respectively. See File Status Codes, for additional information.


6.17.42. STOP

STOP Syntax
=======================================================================

 STOP { RUN [ { RETURNING|GIVING { literal-1    }           } ] }
 ~~~~ { ~~~   { ~~~~~~~~~ ~~~~~~ { identifier-1 }           }   }
      {       {                                             }   }
      {       { WITH { ERROR  } STATUS [ { literal-2    } ] }   }
      {       {      { ~~~~~  }          { identifier-2 }   }   }
      {       {      { NORMAL }                             }   }
      {                ~~~~~~                                   }
      { literal-3                                               }

=======================================================================
  1. The reserved words "STATUS" and "WITH" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved words "RETURNING"
  3. The "RUN"
  4. The <literal-3> clause displays the specified text on the "SYSOUT"/"STDOUT" device, waits for the user to press the Enter key and then — once the key has been pressed — allows the program to continue execution.
  5. The optional "RETURNING" clause provides the opportunity to return a numeric value to the operating system (a "return code"). The manner in which the return code may be interrogated by the operating system varies, but Windows can use "%ERRORLEVEL%" to query the return code while Unix shells such as sh, bash and ksh can query the return code as "$?". Other Unix shells may have different ways to access return code values.
  6. The "STATUS"
  7. Using the "STATUS" clause without a <literal-2> or <identifier-2> will return a return code of 0 if the "NORMAL"
  8. Your program will always return a return code, even if no "RETURNING" or "STATUS" clause is specified. In the absence of the use of these clauses, the value in the "RETURN-CODE" special register (see Special Registers) at the time the "STOP" statement is executed will be used as the return code.
  9. Any programmer-defined exit procedure (established via the "CBL_EXIT_PROC" built-in system subroutine (see CBL_EXIT_PROC)) will be executed by "STOP RUN", but not by "STOP <literal-3>".
  10. Valid return code values can be in the range -2147483648 to +2147483647.
  11. The three code snippets below are all equivalent — they show different ways in which a GnuCOBOL program may be coded to pass a return code value of 16 back to the operating system and then halt.
    STOP RUN RETURNING 16
    
    MOVE 16 TO RETURN-CODE
    STOP RUN
    
    STOP RUN WITH ERROR STATUS 16
    


6.17.43. STRING

STRING Syntax
=======================================================================

   STRING
   ~~~~~~
      { { literal-1    } [ DELIMITED BY { SIZE         } ] }...
        { identifier-1 }   ~~~~~~~~~    { ~~~~         }
                                        { literal-2    }
        INTO identifier-3               { identifier-2 }
        ~~~~
      [ WITH POINTER identifier-4 ]
             ~~~~~~~
      [ ON OVERFLOW imperative-statement-1 ]
           ~~~~~~~~
      [ NOT ON OVERFLOW imperative-statement-2 ]
        ~~~    ~~~~~~~~
 [ END-STRING ]
   ~~~~~~~~~~

=======================================================================
  1. The reserved words "BY", "ON" and "WITH" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. All literals and identifiers (except for <identifier-4>) must be explicitly or implicitly defined with a "USAGE" (see USAGE) of "DISPLAY". Any of the identifiers may be group items.
  3. The "POINTER"
  4. Each <literal-1> / <identifier-1> will be referred to as a source item. The receiving data item is <identifier-3>.
  5. The "STRING" statement’s processing is based upon a ’current character pointer
  6. For each source item, the contents of the sending item will be copied — character-by-character — into <identifier-3> at the character position specified by the current character pointer. After each character is copied, the current character pointer will be incremented by 1 so that it points to the position within <identifier-3> where the next character should be copied.
  7. The "DELIMITED BY"
  8. Using "DELIMITED BY <literal-2>" or "DELIMITED BY <identifier-2>" causes only the contents of the source item up to but not including the character sequence specified by the literal or identifier to be copied.
  9. "STRING" processing will cease when one of the following occurs:
    1. The initial value of the current character pointer is less than 1 or greater than the number of characters in <identifier-3>, or…
    2. The value of the current character pointer exceeds the size of <identifier-3> at the point the STRING statement wants to copy a character into <identifier-3>, or…
    3. All sending items have been fully processed
  10. If event (A) occurs, <identifier-3> will remain unchanged.
  11. The occurrence of either event (A) or (B) triggers what is referred to as an ’overflow condition
  12. The <identifier-3>) is neither automatically initialized (to spaces or any other value) at the start of a "STRING" statement nor will it be space-filled should the total number of sending item characters copied into it be less than its size. You may explicitly initialize <identifier-3> yourself via the "INITIALIZE" (see INITIALIZE) or "MOVE" (see MOVE) statements before executing the "STRING" if you wish.
  13. The optional "ON OVERFLOW" and "NOT ON OVERFLOW" clauses may be used to detect and react to the occurrence or not, respectively, of an overflow condition. See ON OVERFLOW + NOT ON OVERFLOW, for additional information.


6.17.44. SUBTRACT



6.17.44.1. SUBTRACT FROM

SUBTRACT FROM Syntax
=======================================================================

   SUBTRACT { literal-1    }... FROM { identifier-2
   ~~~~~~~~ { identifier-1 }    ~~~~

          [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ] }...
            ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                              { NEAREST-AWAY-FROM-ZERO }
                              { ~~~~~~~~~~~~~~~~~~~~~~ }
                              { NEAREST-EVEN           }
                              { ~~~~~~~~~~~~           }
                              { NEAREST-TOWARD-ZERO    }
                              { ~~~~~~~~~~~~~~~~~~~    }
                              { PROHIBITED             }
                              { ~~~~~~~~~~             }
                              { TOWARD-GREATER         }
                              { ~~~~~~~~~~~~~~         }
                              { TOWARD-LESSER          }
                              { ~~~~~~~~~~~~~          }
                              { TRUNCATION             }
                                ~~~~~~~~~~
     [ ON SIZE ERROR imperative-statement-1 ]
          ~~~~ ~~~~~
     [ NOT ON SIZE ERROR imperative-statement-2 ]
       ~~~    ~~~~ ~~~~~
 [ END-SUBTRACT ]
   ~~~~~~~~~~~~

=======================================================================
  1. The reserved words "IS" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. Both <identifier-1> and <identifier-2> must be numeric unedited data items.
  3. <literal-1> must be a numeric literal.
  4. The optional "ROUNDED" (see ROUNDED) clause available to each <identifier-2> will control how non-integer results will be saved.
  5. The optional "ON SIZE ERROR" and "NOT ON SIZE ERROR" clauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-2> with an insufficient number of digit positions available to the left of any implied decimal point. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information.


6.17.44.2. SUBTRACT GIVING

SUBTRACT GIVING Syntax
=======================================================================

   SUBTRACT { literal-1    }... FROM identifier-2
   ~~~~~~~~ { identifier-1 }    ~~~~

       GIVING { identifier-3
       ~~~~~~
          [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ] }...
            ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                              { NEAREST-AWAY-FROM-ZERO }
                              { ~~~~~~~~~~~~~~~~~~~~~~ }
                              { NEAREST-EVEN           }
                              { ~~~~~~~~~~~~           }
                              { NEAREST-TOWARD-ZERO    }
                              { ~~~~~~~~~~~~~~~~~~~    }
                              { PROHIBITED             }
                              { ~~~~~~~~~~             }
                              { TOWARD-GREATER         }
                              { ~~~~~~~~~~~~~~         }
                              { TOWARD-LESSER          }
                              { ~~~~~~~~~~~~~          }
                              { TRUNCATION             }
                                ~~~~~~~~~~
     [ ON SIZE ERROR imperative-statement-1 ]
          ~~~~ ~~~~~
     [ NOT ON SIZE ERROR imperative-statement-2 ]
       ~~~    ~~~~ ~~~~~
 [ END-SUBTRACT ]
   ~~~~~~~~~~~~

=======================================================================
  1. The reserved words "IS" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. Both <identifier-1> and <identifier-2> must be numeric unedited data items.
  3. <literal-1> must be a numeric literal.
  4. <identifier-3> must be a numeric (edited or unedited) data item.
  5. The optional "ROUNDED" (see ROUNDED) clause available to each <identifier-2> will control how non-integer results will be saved.
  6. The optional "ON SIZE ERROR" and "NOT ON SIZE ERROR" clauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-2> with an insufficient number of digit positions available to the left of any implied decimal point. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information.


6.17.44.3. SUBTRACT CORRESPONDING

SUBTRACT CORRESPONDING Syntax
=======================================================================

   SUBTRACT CORRESPONDING identifier-1 FROM identifier-2
   ~~~~~~~~                            ~~~~
     [ ROUNDED [ MODE IS { AWAY-FROM-ZERO         } ] ]
       ~~~~~~~   ~~~~    { ~~~~~~~~~~~~~~         }
                         { NEAREST-AWAY-FROM-ZERO }
                         { ~~~~~~~~~~~~~~~~~~~~~~ }
                         { NEAREST-EVEN           }
                         { ~~~~~~~~~~~~           }
                         { NEAREST-TOWARD-ZERO    }
                         { ~~~~~~~~~~~~~~~~~~~    }
                         { PROHIBITED             }
                         { ~~~~~~~~~~             }
                         { TOWARD-GREATER         }
                         { ~~~~~~~~~~~~~~         }
                         { TOWARD-LESSER          }
                         { ~~~~~~~~~~~~~          }
                         { TRUNCATION             }
                           ~~~~~~~~~~
     [ ON SIZE ERROR imperative-statement-1 ]
          ~~~~ ~~~~~
     [ NOT ON SIZE ERROR imperative-statement-2 ]
       ~~~    ~~~~ ~~~~~
 [ END-SUBTRACT ]
   ~~~~~~~~~~~~

=======================================================================
  1. The reserved words "IS" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. Both <identifier-1> and <identifier-2> must be group items.
  3. See CORRESPONDING, for information on how corresponding matches will be found between <identifier-1> and <identifier-2>.
  4. The optional "ROUNDED" (see ROUNDED) clause available to each <identifier-2> will control how non-integer results will be saved.
  5. The optional "ON SIZE ERROR" and "NOT ON SIZE ERROR" clauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-2> with an insufficient number of digit positions available to the left of any implied decimal point. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information.


6.17.45. SUPPRESS

SUPPRESS Syntax
=======================================================================

 SUPPRESS PRINTING
 ~~~~~~~~

=======================================================================
  1. The reserved word "PRINTING" is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program.
  2. This statement may only appear within a "USE BEFORE REPORTING" procedure (in "DECLARATIVES" (see DECLARATIVES)).
  3. "SUPPRESS" only prevents the presentation of the report group within whose "USE BEFORE REPORTING" procedure the statement occurs.
  4. This statement must be executed each time presentation of the report group is to be suppressed.
  5. When a report group’s presentation is suppressed, none of the following operations for the report will take place:
    1. Actual presentation of the report group in question.
    2. Processing of any "LINE" (see LINE) clauses within the report group in question.
    3. Processing of the "NEXT GROUP" (see NEXT GROUP) clause (if any) within the report group in question.
    4. Any modification to the "LINE-COUNTER" special register (see Special Registers).
    5. Any modification to the "PAGE-COUNTER" special register .


6.17.46. TERMINATE

TERMINATE Syntax
=======================================================================

 TERMINATE report-name-1...
 ~~~~~~~~~

=======================================================================
  1. Each <report-name-1> must be the name of a report having an "RD" (see REPORT SECTION) defined for it.
  2. The specified report name(s) must be currently initiated (via "INITIATE" (see INITIATE)) and cannot yet have been terminated.
  3. The "TERMINATE" statement will present each "CONTROL FOOTING" (if any), in reverse sequence of the control hierarchy, starting with the most minor up to "FINAL" (if any). During the presentation of these groups and the processing of any "USE BEFORE REPORTING" procedures for those groups, the prior set of control data item values will be available, as though a control break had been detected at the most major control data name.
  4. During the presentation of the "CONTROL FOOTING" groups, any necessary "PAGE FOOTING" and "PAGE HEADING" groups will be presented as well.
  5. Finally,the "REPORT FOOTING" group, if any, will be presented.
  6. If an "INITIATE" is followed by a "TERMINATE" with no intervening "GENERATE" (see GENERATE) statements (all pertaining to the same report, of course), no report groups will be presented to the output file.


6.17.47. TRANSFORM

TRANSFORM Syntax
=======================================================================

 TRANSFORM identifier-1 FROM { literal-1    } TO { literal-2    }
 ~~~~~~~~~              ~~~~ { identifier-2 } ~~ { identifier-3 }

=======================================================================
  1. Both <literal-1> and/or <literal-2> must be alphanumeric literals.
  2. All of <identifier-1>, <identifier-2> and <identifier-3> must either be group items or alphanumeric data items. Numeric data items with a "USAGE" (see USAGE) of "DISPLAY" are accepted, but will generate warning messages from the compiler.
  3. The "TRANSFORM" statement will replace characters within <identifier-1> that are found in the string specified before the "TO" keyword with the corresponding characters from the string specified after the "TO" keyword.
  4. This statement exists within GnuCOBOL to provide compatibility with COBOL programs written to pre-1985 standards. The "TRANSFORM" statement was made obsolete in the 1985 standard of COBOL, having been replaced by the "CONVERTING" clause of the "INSPECT" statement (see INSPECT). New programs should be coded to use "INSPECT CONVERTING" rather than "TRANSFORM".


6.17.48. UNLOCK

UNLOCK Syntax
=======================================================================

 UNLOCK filename-1 RECORD|RECORDS
 ~~~~~~

=======================================================================
  1. The reserved words "RECORD" and "RECORDS" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. If <file-name-1> is a Sort/Merge work file, no action will be taken.
  3. Not all GnuCOBOL implementations support locking. Whether they do or not depends upon the operating system they were built for and the build options that were used when GnuCOBOL was generated. When a program using one of those GnuCOBOL implementations issues an UNLOCK, it will ignored. There will be no compiler message issued. Buffer syncing, if needed, will still occur.
  4. See Record Locking, for additional information on record locking.


6.17.49. UNSTRING

UNSTRING Syntax
=======================================================================

   UNSTRING identifier-1
   ~~~~~~~~
        DELIMITED BY { [ ALL ] literal-1 } [ OR { [ ALL ] literal-2 } ]...
        ~~~~~~~~~    {   ~~~             }   ~~ {   ~~~             }
                     { identifier-2      }      { identifier-3      }

        INTO { identifier-4
        ~~~~ [ DELIMITER IN identifier-5 ] [ COUNT IN identifier-6 ] }...
               ~~~~~~~~~                     ~~~~~
      [ WITH POINTER identifier-7 ]
             ~~~~~~~
      [ TALLYING IN identifier-8 ]
        ~~~~~~~~
      [ ON OVERFLOW imperative-statement-1 ]
           ~~~~~~~~
      [ NOT ON OVERFLOW imperative-statement-2 ]
        ~~~    ~~~~~~~~
 [ END-UNSTRING ]
   ~~~~~~~~~~~~

=======================================================================
  1. The reserved words "BY", "IN" and "ON" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. <identifier-1> through <identifier-5> must be explicitly or implicitly defined with a "USAGE" (see USAGE) of "DISPLAY". Any of those identifiers may be group items.
  3. Both <literal-1> and <literal-2> must be alphanumeric literals.
  4. Each of <identifier-6>, <identifier-7> and <identifier-8> must be elementary non-edited integer numeric items.
  5. At the time the "UNSTRING" statement begins execution, <identifier-7> must have a value greater than 0.
  6. <identifier-1> will be referred to as the ’source string’ and each <identifier-4> will be referred to as a ’destination field’ in the following discussions.
  7. The "UNSTRING" statement’s processing is based upon a ’current character pointer’, the initial value of which will be the value of <identifier-7> at the time the "UNSTRING" statement began execution. If no "POINTER" clause is coded, a value of 1 (meaning "the 1st character position") will be assumed for the current character pointer’s initial value.
  8. The source string will be parsed into sub strings starting from the current character pointer position. Sub strings are identified by using the various delimiter strings specified on the "DELIMITED BY"
  9. Using the "ALL"
  10. Two consecutive delimiter sequences will identify a null sub string.
  11. Identified sub strings will be moved into each destination field in the sequence they are identified; values moved into a destination field will be truncated if the sub string length exceeds the destination field length, or padded with spaces if the destination field length exceeds the sub string length. Both truncation and padding will be controlled by the presence or absence of a "JUSTIFIED" (see JUSTIFIED) clause on the destination field.
  12. Each destination field may have an optional "DELIMITER"
  13. Each destination field may have an optional "COUNT"
  14. If a "TALLYING" clause is coded, <identifier-8> will be incremented by 1 each time a destination field is populated.
  15. None of <identifier-4>, <identifier-5>, <identifier-6>, <identifier-7> or <identifier-8> are initialized by the "UNSTRING" statement. You need to do that yourself via a "MOVE" (see MOVE) or "INITIALIZE" statement (see INITIALIZE).
  16. "UNSTRING" processing will cease when one of the following occurs:
    1. The initial value of the current character pointer is less than 1 or greater than the number of character positions in <identifier-1>, or…
    2. All destination fields have been fully processed
  17. If event (A) occurs, none of the destination field contents (or the contents of their "DELIMITER" or <COUNT> identifiers) will be changed.
  18. An ’overflow’ condition exists if either event (A) occurs, or if event (B) occurs with at least one character position in <identifier-1> not having been processed.
  19. The optional "ON OVERFLOW" and "NOT ON OVERFLOW" clauses may be used to detect and react to the occurrence or not, respectively, of an overflow condition. See ON OVERFLOW + NOT ON OVERFLOW, for additional information.

The following sample program illustrates the "UNSTRING" statement statement.

IDENTIFICATION DIVISION.
PROGRAM-ID. DEMOUNSTRING.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  Full-Name                   PIC X(40).
01  Parsed-Info.
    05 Last-Name                PIC X(15).
    05 First-Name               PIC X(15).
    05 MI                       PIC X(1).
    05 Delim-LN                 PIC X(1).
    05 Delim-FN                 PIC X(1).
    05 Delim-MI                 PIC X(1).
    05 Count-LN                 BINARY-CHAR.
    05 Count-FN                 BINARY-CHAR.
    05 Count-MI                 BINARY-CHAR.
    05 Tallying-Ctr             BINARY-CHAR.
PROCEDURE DIVISION.
P1. PERFORM UNTIL EXIT
      DISPLAY "Enter Full Name (null quits):"
          WITH NO ADVANCING
      ACCEPT Full-Name
      IF Full-Name = SPACES
        EXIT PERFORM
      END-IF
      INITIALIZE Parsed-Info
      UNSTRING Full-Name
        DELIMITED BY ", "
                  OR ","
                  OR ALL SPACES
        INTO Last-Name
                 DELIMITER IN Delim-LN
                 COUNT IN Count-LN
             First-Name
                 DELIMITER IN Delim-FN
                 COUNT IN Count-FN
             MI
                 DELIMITER IN Delim-MI
                 COUNT IN Count-MI
        TALLYING Tallying-Ctr
    DISPLAY "First-Name=" First-Name
            " Delim='"    Delim-FN
            "' Count="    Count-FN
    DISPLAY "MI        =" MI "              "
            " Delim='"    Delim-MI
            "' Count="    Count-MI
    DISPLAY "Last-Name =" Last-Name
            " Delim='"    Delim-LN
            "' Count="    Count-LN
    DISPLAY "Tally=     " Tallying-Ctr
  END-PERFORM
  DISPLAY "Bye!"
  STOP RUN   .

The following is sample output from the program:

Enter Full Name (null quits):Cutler, Gary L
First-Name=Gary            Delim=' ' Count=+004
MI        =L               Delim=' ' Count=+001
Last-Name =Cutler          Delim=',' Count=+006
Tally=     +003
Enter Full Name (null quits):Snoddgrass,Throckmorton,P
First-Name=Throckmorton    Delim=',' Count=+012
MI        =P               Delim=' ' Count=+001
Last-Name =Snoddgrass      Delim=',' Count=+010
Tally=     +003
Enter Full Name (null quits):Munster   Herman
First-Name=Herman          Delim=' ' Count=+006
MI        =                Delim=' ' Count=+000
Last-Name =Munster         Delim=' ' Count=+007
Tally=     +002
Enter Full Name (null quits):
Bye!


6.17.50. WRITE

WRITE Syntax
=======================================================================

   WRITE record-name-1
   ~~~~~
      [ FROM { literal-1    } ]
        ~~~~ { identifier-1 }

      [ WITH [ NO ] LOCK ]
               ~~   ~~~~
      [ { BEFORE } ADVANCING { { literal-2    } LINE|LINES } ]
        { ~~~~~~ }           { { identifier-2              }
        { AFTER  }           { PAGE                        }
          ~~~~~              { ~~~~                        }
                             { mnemonic-name-1             }

      [ AT END-OF-PAGE|EOP imperative-statement-1 ]
           ~~~~~~~~~~~ ~~~
      [ NOT AT END-OF-PAGE|EOP imperative-statement-2 ]
        ~~~    ~~~~~~~~~~~ ~~~
      [ INVALID KEY imperative-statement-3 ]
        ~~~~~~~
      [ NOT INVALID KEY imperative-statement-4 ]
        ~~~ ~~~~~~~
 [ END-WRITE ]
   ~~~~~~~~~

=======================================================================
  1. The reserved words "ADVANCING", "AT", "KEY", "LINE", "LINES" and "WITH" are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program.
  2. The reserved words "END-OF-PAGE" and "EOP" are interchangeable.
  3. The <record-name-1> specified on the statement must be defined as an 01-level record subordinate to the File Description ("FD" (see File/Sort-Description)) of a file that is currently open for "OUTPUT" (see File OPEN Modes), "EXTEND" or "I-O".
  4. The optional "FROM"
  5. The optional "LOCK" options may be used to manually control access to the just-written record by other programs while this program is running. See Record Locking, to review the various record locking behaviour.
  6. The optional "INVALID KEY" and "NOT INVALID KEY" clauses may be used when writing to relative or indexed files to detect and react to the failure (non-zero file status code) or success (00 file status code), respectively, of the statement. See File Status Codes, for additional information.
  7. When "WRITE" is used against an "ORGANIZATION LINE SEQUENTIAL" (see ORGANIZATION LINE SEQUENTIAL) file, with or without the "LINE ADVANCING" (see LINE ADVANCING) option, an end-of-record delimiter character sequence will be written to the file to signify where one record ends and the next record begins. This delimiter sequence will be either of the following:
  8. The following points pertain to the use (or not) of the "ADVANCING" clause:
    1. Using this clause with any organization other than "ORGANIZATION LINE SEQUENTIAL" will either be rejected outright by the compiler (relative or indexed files) or may introduce unwanted characters into the file ("ORGANIZATION SEQUENTIAL" (see ORGANIZATION SEQUENTIAL)).
    2. If no "ADVANCING" clause is specified on a "WRITE" to a line-advancing file, "AFTER ADVANCING 1 LINE" will be assumed; on other than line-advancing files, "BEFORE ADVANCING 1 LINE" will be assumed.
    3. When "BEFORE ADVANCING"
    4. If "AFTER ADVANCING"
    5. The "ADVANCING n LINES" clause will introduce the specified number of line-terminator character sequences into the file either before the written record ("AFTER ADVANCING") or after the written record ("BEFORE ADVANCING").
    6. If the "LINAGE" (see File/Sort-Description) clause is absent from the file’s "FD":
      1. The "ADVANCING PAGE"
      2. Management of areas on the printed page such as top-of page headers, bottom-of-page footers, dealing with "full page" situations and the like are the complete responsibility of the programmer.
    7. If the LINAGE clause is present in the file’s "FD":
      1. The "ADVANCING PAGE" clause will introduce the appropriate number of line-terminator character sequences into the file either before the written record ("AFTER ADVANCING") or after the written record ("BEFORE ADVANCING") so as to force the printer to automatically advance to a new sheet of paper when the file prints. No formfeed characters will be generated when "LINAGE" is specified — instead, it is assumed that the printer to which the report will be printed will be loaded with special forms that conform to the specifications defined by the "LINAGE" clause.
      2. Management of areas on the printed page such as top-of page headers, bottom-of-page footers, dealing with "full page" situations and the like are now the joint responsibility of the programmer and the GnuCOBOL run-time library, which provides tools such as the "LINAGE-COUNTER" special register (see Special Registers) and the "END-OF-PAGE"
      3. The "AT END-OF-PAGE" clause will be triggered, thus executing <imperative-statement-1> (see Imperative Statement), if the "WRITE" statement introduces a data line or line-feed character into the file at a line position within the Page Footer area defined by the "LINAGE" clause. The "NOT AT END-OF-PAGE" clause will be triggered (thus executing <imperative-statement-2>) if no end-of-page condition occurred during the "WRITE".

7. Report Writer Usage Notes



7.1. RWCS Lexicon

Please see availability notes on this at 1.3.13. There are a number of terms that describe various aspects of the operation of the Report Writer Control System (RWCS). Understanding the meanings of these terms is vital to developing an understanding of the subject.

Control Break

An event that is triggered when a control field on an RWCS-generated report changes value. It is these events that trigger the generation of control heading and control footing groups.

Control Field

A field of data being presented within a detail group; as the various detail groups that comprise the report are presented, they are presumed to appear in sorted sequence of the control fields contained within them. As an example, a department-by-department sales report for a chain of stores would probably be sorted by store number and – within like store numbers – be further sorted by department number. The store number will undoubtedly serve as a control field for the report, allowing control heading groups to be presented before each sequence of detail groups for the same store and control footing groups to be presented after each such sequence.

Control Footing

A report group that appears immediately after one or more detail groups of an RWCS-generated report. Such are produced automatically as a result of a control break. This type of group typically serves as a summary of the detail group(s) that precede it, as might be the case on a sales report for a chain of stores, where the detail groups documenting sales for each department (one department per detail group) from the same store might be followed by a control footing that provides a summation of the department-by-department sales for that store.

Control Heading

A report group that appears immediately before one or more detail groups of an RWCS-generated report. Such are produced automatically as a result of a control break. This type of group typically serves as an introduction to the detail group(s) that follow, as might be the case on a sales report for a chain of stores, where the detail groups documenting sales for each department (one department per detail group) from the same store might be preceded by a control heading that states the full name and location of the store.

Detail Group

A report group that contains the detailed data being presented for the report.

Page Footing

A report group that appears at the bottom of every page of an RWCS-generated report. Information typically found within such a report group might be:

Page Heading

A report group that appears at the top of every page of an RWCS-generated report. Information typically found within such a report group might be:

Report Footing

A report group that occurs only once in an RWCS-generated report — as the very last presented report group of the report. These typically serve as a visual indication that the report is finished.

Report Group

One or more consecutive lines on a report that serve a common informational purpose or function. For example, lines of text that are displayed at the top or bottom of every printed page of a report.

Report Heading

A report group that occurs only once in an RWCS-generated report — as the very first presented report group of the report. These typically serve as an introduction to the report.



7.2. The Anatomy of a Report

Every report has the same basic structure, as shown here, even though not all reports will have all of the groups shown. In fact, it is a very unusual report indeed that actually has every one of these groups:

[1]Presented throughout the report, as needed
[2]Repeated, as needed

These groups will be presented (printed) across however many formatted pages are necessary to hold them. No single report group will be allowed to cross page boundaries.

The management of paging, enforcement of the "groups cannot span pages" rule and almost every aspect of report generation are handled entirely by the Report Writer Control System.



7.3. The Anatomy of a Report Page

Each page of a report is divided into as many as five (5) areas, as shown in the following diagram.

  _______________________________ 
 |                               |
 | Top-of-page Unusable Area    |—# Lines: LINES AT TOP (LINAGE)
 |_______________________________|
 |                               |—Line #: HEADING (RD)
 | Heading Area                  |
 |_______________________________|—Line #: FIRST DETAIL (RD) - 1
 |                               |—Line #: FIRST DETAIL (RD)
 |                               |
 | Body Area                     |—Line #: LAST CONTROL HEADING (RD)
 |                               |—Line #: LAST DETAIL (RD)
 |_______________________________|—Line #: FOOTING (RD)
 |                               |—Line #: FOOTING (RD) + 1
 | Footing Area                  |
 |_______________________________|
 |                               |
 | Bottom-of-page Unusable Area |—# Lines: LINES AT BOTTOM (LINAGE)
 |_______________________________|

When describing a report via the "RD" (see REPORT SECTION) clause, the total number of usable lines are specified as the "PAGE LIMIT" value; this value is the sum of the number of lines contained in the Heading, Body and Footing Areas.

The unusable areas of a page (if any) will appear above and below that usable area. You don’t specify the unusable area in the "RD", but rather using a "LINAGE" (see File/Sort-Description) clause in the "FD" of the file the report is "attached" to.

The various report groups will be presentable in the various areas of a page, as follows:

"REPORT HEADING"

Heading Area — An exception to this is the situation where the report heading report group contains the "NEXT GROUP NEXT PAGE" (see NEXT GROUP) option; in those cases, the report heading will be presented on a page by itself (anywhere on that page) at the beginning of the report.

"PAGE HEADING"

Heading Area

"CONTROL HEADING"

Body Area, but no line of a control heading is allowed past the line number specified by "LAST CONTROL HEADING"

"DETAIL"

Body Area, but no line of a detail report group is allowed past the line number specified by "LAST DETAIL"

"CONTROL FOOTING"

Body Area, but no line of a control footing report group is allowed past the line number specified by "FOOTING"

"PAGE FOOTING"

Footing Area

"REPORT FOOTING"

Footing Area — An exception to this is the situation where the report footing report group contains the "NEXT PAGE" option in its "LINE" (see LINE) clause; in those cases, the report footing will be presented on a page by itself at the end of the report.



7.4. How RWCS Builds Report Pages

A report created via a "WRITE" statement (see WRITE) will contain carriage-control information. Most notably, ASCII form-feed characters (X’0C’) will be written to the report file to support the statement’s "ADVANCING PAGE" option. Whether the data for a report line created via "ADVANCING PAGE" occurs before or after the form-feed character depends upon whether the programmer coded "WRITE <record-name> BEFORE ADVANCING PAGE" or "WRITE <record-name> AFTER ADVANCING PAGE", respectively.

The GnuCOBOL implementation of RWCS does not issue any carriage-control information to the report files it produces — instead, it relies upon the information coded in the "RD" for the report (specifically the "PAGE LIMITS" and related options) and it’s internally-generated and managed "LINE-COUNTER" special register (see Special Registers) for the report to know when to issue any blank lines to the file to fill-out the end of a printed page.

Because this is the way the GnuCOBOL RWCS works, in order to design an RWCS-generated report you’ll need to know answers to the following questions:

  1. What printer(s) will the report be printed on?
  2. What paper orientation will you use, — Landscape (long edge of the paper at the top and bottom of page), or Portrait (long edge of the paper at the left and right of page)?
  3. What tool will be used to print the report (direct printing to the device, notepad.exe, MS-Word, …)?
  4. What font and font size will be used for the report when it is printed? RWCS-generated reports will assume that a fixed-width font such as "Courier", "Lucida Console", "Consolas" and the like will be used to print, as variable-pitch fonts would make the proper alignment of columns of data on reports virtually impossible.
  5. When unprintable area exists at all four margins of the paper? These are generally caused by the printer itself or by its software driver.
  6. What is the maximum number of lines per page that may be printed on a single sheet of paper?
  7. What is the maximum number of characters that may be printed on one line?

Once you know the answer to questions 1-4, you may easily determine the answers to the remaining questions as follows:

  1. Prepare a text file containing 100 or so records, each consisting of a numeric scale ("123456789012345678901234"…).
  2. Print the file in a manner consistent with your answers to questions 1-4.
  3. Add any necessary additional digits to each record in your test file (if lines weren’t full) or remove characters from the end of each record if lines wrapped. If you made changes, reprint the file.
  4. Now that you know exactly how long each record may be, add additional records and reprint. Continue until printing overflows to a second page.
  5. The first page you print is now a perfect template to use when designing reports — it shows, given the answers to questions 1-4, every available printable character position on a page! The number of lines printed on that page becomes your "PAGE LIMIT" value for the "RD".

The remaining "PAGE LIMIT" values can be established as required by your report(s).

Using <identifier> rather than <integer> specifications in the "RD" will give your program the ability — at run time — to accommodate multiple printers, fonts, font sizes and paper orientation. Just follow the above steps for each combination you wish your program to support.



7.5. Control Hierarchy

Every report that employs control breaks has a natural hierarchy of those control breaks based upon the manner in which the data the report is being generated from is sorted. This concept is best understood using an example which assumes a COBOL program to process sales data collected from every computerized cash register across a chain of stores having multiple departments is being developed.

The application that collects data from the various cash registers at each store will generate data records that look like this to a COBOL program:

01  Sales-For-Register.
    05 Sales-Date            PIC 9(8).
    05 Time-Collected        PIC 9(6).
    05 Register-Number       PIC 9(7).
    05 Store-Number          PIC 9(3).
    05 Department-Number     PIC 9(3).
    05 Total-Sales           PIC 9(6)V99.

Your task is to develop a report that shows the sales total from each cash register and summarizes those sales by department within each store, by store and also generates a total sales figure for the day across all stores.

To accomplish this, you will use a "SORT" statement (see SORT) to sort the file of cash register sales data into:

  1. Ascending sequence of store number
  2. Within each store, data will be sorted into ascending sequence of department number
  3. If there are multiple cash registers in a particular department of a specific store, the data needs to be further sorted so that the cash registers are ordered in sequence of their register number.

So, assuming a sort file has been defined and it’s record layout (essentially a mirror of the raw data file) is defined as follows:

01  Sorted-Sales-For-Register.
    05 Sorted-Sales-Date            PIC 9(8).
    05 Sorted-Time-Collected        PIC 9(6).
    05 Sorted-Register-Number       PIC 9(7).
    05 Sorted-Store-Number          PIC 9(3).
    05 Sorted-Department-Number     PIC 9(3).
    05 Sorted-Total-Sales           PIC 9(6)V99.

Then the "SORT" statement to accomplish the desired sequencing would be:

SORT SORT-FILE
    ASCENDING KEY Sorted-Store-Number
                  Sorted-Department-Number
                  Sorted-Register-Number
    USING Input-file
    OUTPUT PROCEDURE 100-Generate-Report

As a result of the sort, our program might expect to see data somewhat like this (date, time and sales totals are shown as "…"):

   +-------------------- Register Number
   |      +------------- Store Number
   |      |  +---------- Department Number
   |      |  |
...0535240001001...
...0589130001001...
...0625174001001...
...0122234001002...
...0732345001002...
...0003423001003...
...2038774001004...
...0112646002001...
...9963348002002...
...3245677002003...
...4456778002003...
...0002345002004...

Because of the sort, the most-frequently changing value of the three sort keys will be that of Sorted-Register-Number. This essentially defines the "detail" level of the report.

The next most-frequently changing value is that of Sorted-Department-Number, and the least-frequently changing value is that of Sorted-Store-Number. remember that the program should be generating totals each time one of these two values change, plus a grand total of sales at the end of the report. These three points are the ’Control Break

When the report is defined, it’s "RD" would contain a "CONTROLS ARE" clause that lists the control breaks in least- to most-frequent sequence of changing. This would be coded as:

"CONTROLS ARE FINAL, Sorted-Store-Number, Sorted-Department-Number"

A FINAL control break only occurs once, at the very end of the report. The "CONTROL FOOTING" for this break will be the one that produces the grand total of sales for all stores.

The next break listed on the "CONTROLS" clause will be the one that occurs next most-frequently (Sorted-Store-Number). This control break will be the one that produces the summation for each entire store, and will have its own "CONTROL FOOTING".

The next (and last, in this case) break listed on the CONTROLS clause will be the one that occurs even more frequently (Sorted-Department-Number). The "CONTROL FOOTING" for this control field will be the one that summarizes sales for each department within a store.

This sequence of control breaks from least- to most-frequent (in other words, in the order they occur on the CONTROLS ARE clause) is the ’control hierarchy’ of the report; control breaks that occur more frequently than others are said to be at a lower level in the control hierarchy.

Defining a control hierarchy (via "CONTROLS ARE") that does not match the actual sequence in which data will be processed is a great way to guarantee a "broken" report. I’ll show you an example in a later section.



7.6. An Example

This section contains an example of the RWCS at work. The complete program, presented here, is a stripped-down version of a program I have used to generate a report for a class I teach on PC hardware. This report will provide benchmark statistics on a variety of popular AMD and Intel CPUs. The data for the report was obtained from the website www.cpubenchmark.net in December of 2013. By the time you are reading this, that data will most likely have become rather out-of-date, but it illustrates RWCS well enough.



7.6.1. Data

Here is the data that the program will be reading. Each record reflects the aggregated benchmark scoring for one particular CPU, as scores for benchmarks against that CPU have been reported to the cpubenchmark.net website by their PassMark benchmark software. The data consists of four fields. Fields are separated from one another by a single comma. The descriptions of the fields are as follows:

Benchmark Score

A five-digit number showing the aggregated benchmark scores for the CPU; the higher this number, the better the CPU performed in benchmark testing.

Vendor

The name of the vendor who makes the CPU. In this data, that will either be "AMD" (American Micro Devices) or "INTEL".

Family

The 7-character family of CPU products the CPU falls into. This will have values such as "A4", "A10", "Core i5", "Core i7", etc.

Model

The specific model of CPU within the family.


The first record of data shown below shows that the aggregated score of all benchmarks reported for the AMD A10-4600M CPU is 3145, as compared to the second record which shows that the aggregated score reported of all benchmarks reported for the Intel Core-i7-4960X CPU is 14291.

The following is the complete set of input data used for this example. This is by no means the complete set of data available at cpubenchmark.net –– it is just a representative sample used for this example. For my class, I give my students a report showing the results for almost a thousand CPUs.

For the sake of brevity, this document lists the data in three columns.

03145,AMD,A10,4600M            05421,AMD,FX,6100              03917,Intel,Core i5,4300U
14291,Intel,Core i7,4960X      05813,AMD,FX,6120              01743,Intel,Core i5,4300Y
02505,AMD,A10,4655M            06194,AMD,FX,6200              04804,Intel,Core i5,4330M
03449,AMD,A10,4657M            06388,AMD,FX,6300              03604,Intel,Core i5,4350U
04251,AMD,A10,5700             07017,AMD,FX,6350              06282,Intel,Core i5,4430
02758,AMD,A10,5745M            06163,AMD,FX,8100              05954,Intel,Core i5,4430S
03332,AMD,A10,5750M            06605,AMD,FX,8120              06517,Intel,Core i5,4440
03253,AMD,A10,5757M            06845,AMD,FX,8140              07061,Intel,Core i5,4570
04798,AMD,A10,5800B            07719,AMD,FX,8150              06474,Intel,Core i5,4570R
04677,AMD,A10,5800K            08131,AMD,FX,8320              06803,Intel,Core i5,4570S
04767,AMD,A10,6700             09067,AMD,FX,8350              02503,Intel,Core i5,4570T
05062,AMD,A10,6800K            09807,AMD,FX,9370              07492,Intel,Core i5,4670
00677,AMD,A4,1200              10479,AMD,FX,9590              07565,Intel,Core i5,4670K
00559,AMD,A4,1250              03076,Intel,Core i3,3110M      06351,Intel,Core i5,4670T
01583,AMD,A4,3300              03301,Intel,Core i3,3120M      03701,Intel,Core i7,3517U
01237,AMD,A4,3300M             03655,Intel,Core i3,3130M      03449,Intel,Core i7,3517UE
01227,AMD,A4,3305M             03820,Intel,Core i3,3210       04588,Intel,Core i7,3520M
01263,AMD,A4,3310MX            02266,Intel,Core i3,3217U      03912,Intel,Core i7,3537U
01193,AMD,A4,3320M             04219,Intel,Core i3,3220       04861,Intel,Core i7,3540M
01343,AMD,A4,3330MX            03724,Intel,Core i3,3220T      04009,Intel,Core i7,3555LE
01625,AMD,A4,3400              04407,Intel,Core i3,3225       06144,Intel,Core i7,3610QE
01768,AMD,A4,3420              02575,Intel,Core i3,3227U      07532,Intel,Core i7,3610QM
01685,AMD,A4,4300M             01885,Intel,Core i3,3229Y      06988,Intel,Core i7,3612QE
01169,AMD,A4,4355M             04259,Intel,Core i3,3240       06907,Intel,Core i7,3612QM
01919,AMD,A4,5000              03793,Intel,Core i3,3240T      05495,Intel,Core i7,3615QE
01973,AMD,A4,5150M             04414,Intel,Core i3,3245       07310,Intel,Core i7,3615QM
02078,AMD,A4,5300              04757,Intel,Core i3,3250       07759,Intel,Core i7,3630QM
01632,AMD,A4,5300B             03443,Intel,Core i3,4000M      07055,Intel,Core i7,3632QM
02305,AMD,A4,6300              02459,Intel,Core i3,4010U      06516,Intel,Core i7,3635QM
01634,AMD,A6,1450              02003,Intel,Core i3,4010Y      04032,Intel,Core i7,3667U
01964,AMD,A6,3400M             04904,Intel,Core i3,4130       04271,Intel,Core i7,3687U
02101,AMD,A6,3410MX            04041,Intel,Core i3,4130T      03479,Intel,Core i7,3689Y
02078,AMD,A6,3420M             05115,Intel,Core i3,4330       08347,Intel,Core i7,3720QM
02277,AMD,A6,3430MX            05117,Intel,Core i3,4340       08512,Intel,Core i7,3740QM
01995,AMD,A6,3500              03807,Intel,Core i5,3210M      09420,Intel,Core i7,3770
02798,AMD,A6,3600              03995,Intel,Core i5,3230M      09578,Intel,Core i7,3770K
02892,AMD,A6,3620              03126,Intel,Core i5,3317U      09074,Intel,Core i7,3770S
03232,AMD,A6,3650              04101,Intel,Core i5,3320M      08280,Intel,Core i7,3770T
03327,AMD,A6,3670              05902,Intel,Core i5,3330       08995,Intel,Core i7,3820
01630,AMD,A6,4400M             05690,Intel,Core i5,3330S      08548,Intel,Core i7,3820QM
01296,AMD,A6,4455M             05781,Intel,Core i5,3335S      09025,Intel,Core i7,3840QM
02440,AMD,A6,5200              03280,Intel,Core i5,3337U      09196,Intel,Core i7,3920XM
01958,AMD,A6,5350M             02252,Intel,Core i5,3339Y      12107,Intel,Core i7,3930K
01878,AMD,A6,5357M             06282,Intel,Core i5,3340       09052,Intel,Core i7,3940XM
01906,AMD,A6,5400B             04327,Intel,Core i5,3340M      12718,Intel,Core i7,3960X
02174,AMD,A6,5400K             05372,Intel,Core i5,3340S      12823,Intel,Core i7,3970X
02384,AMD,A6,6400K             06199,Intel,Core i5,3350P      03992,Intel,Core i7,4500U
02050,AMD,A8,3500M             04314,Intel,Core i5,3360M      04507,Intel,Core i7,4558U
02426,AMD,A8,3510MX            04555,Intel,Core i5,3380M      04892,Intel,Core i7,4600M
02245,AMD,A8,3520M             03589,Intel,Core i5,3427U      04484,Intel,Core i7,4600U
02276,AMD,A8,3530MX            03479,Intel,Core i5,3437U      03680,Intel,Core i7,4610Y
02866,AMD,A8,3550MX            03057,Intel,Core i5,3439Y      04345,Intel,Core i7,4650U
03215,AMD,A8,3800              06442,Intel,Core i5,3450       07352,Intel,Core i7,4700EQ
03217,AMD,A8,3820              06071,Intel,Core i5,3450S      08161,Intel,Core i7,4700HQ
03552,AMD,A8,3850              06576,Intel,Core i5,3470       07946,Intel,Core i7,4700MQ
03682,AMD,A8,3870K             06077,Intel,Core i5,3470S      08002,Intel,Core i7,4702HQ
02709,AMD,A8,4500M             04591,Intel,Core i5,3470T      07647,Intel,Core i7,4702MQ
02193,AMD,A8,4555M             05991,Intel,Core i5,3475S      08066,Intel,Core i7,4750HQ
04052,AMD,A8,5500              06828,Intel,Core i5,3550       07367,Intel,Core i7,4765T
03464,AMD,A8,5500B             06631,Intel,Core i5,3550S      09969,Intel,Core i7,4770
02434,AMD,A8,5545M             06993,Intel,Core i5,3570       10190,Intel,Core i7,4770K
03052,AMD,A8,5550M             07118,Intel,Core i5,3570K      09803,Intel,Core i7,4770S
02935,AMD,A8,5557M             06709,Intel,Core i5,3570S      08803,Intel,Core i7,4770T
04348,AMD,A8,5600K             05414,Intel,Core i5,3570T      10078,Intel,Core i7,4771
04390,AMD,A8,6500              04333,Intel,Core i5,4200M      08567,Intel,Core i7,4800MQ
04719,AMD,A8,6600K             03355,Intel,Core i5,4200U      09969,Intel,Core i7,4820K
04055,AMD,FX,4100              02358,Intel,Core i5,4200Y      09331,Intel,Core i7,4850HQ
04153,AMD,FX,4130              02382,Intel,Core i5,4210Y      09323,Intel,Core i7,4900MQ
04094,AMD,FX,4150              03482,Intel,Core i5,4250U      13620,Intel,Core i7,4930K
04774,AMD,FX,4170              04381,Intel,Core i5,4258U      09754,Intel,Core i7,4930MX
04711,AMD,FX,4300              04663,Intel,Core i5,4288U      10262,Intel,Core i7,4960HQ
05247,AMD,FX,4350              04786,Intel,Core i5,4300M


7.6.2. Program

Here is the program that will be producing the report. Pay attention to how the data is sorted and how the control hierarchy ("CONTROLS ARE") relates to the "SORT".

IDENTIFICATION DIVISION.
PROGRAM-ID. DEMORWCS.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY. FUNCTION ALL INTRINSIC.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
    SELECT CPU-FILE             ASSIGN TO "CPUDATA.txt"
                                LINE SEQUENTIAL.
    SELECT REPORT-FILE          ASSIGN TO "CPUREPORT.txt"
                                LINE SEQUENTIAL.
    SELECT SORT-FILE            ASSIGN TO DISK.
DATA DIVISION.
FILE SECTION.
FD  CPU-FILE.
01  CPU-REC                     PIC X(26).

FD  REPORT-FILE
    REPORT IS CPU-Report.

SD  SORT-FILE.
01  SORT-REC.
    05 F-SR-Score-NUM           PIC 9(5).
    05 F-SR-Vendor-TXT          PIC X(5).
    05 F-SR-Family-TXT          PIC X(7).
    05 F-SR-Model-TXT           PIC X(6).
WORKING-STORAGE SECTION.
01  WS-Date                     PIC 9(8).

01  WS-Family-Counters.
    05 WS-FC-AVE                PIC 9(5)V99.
    05 WS-FC-Qty                BINARY-LONG.
    05 WS-FC-Total-NUM          BINARY-LONG.

01  WS-Flags.
    05 WS-F-EOF                 PIC X(1).

01  WS-One-Const                PIC 9 VALUE 1.

01  WS-Overall-Counters.
    05 WS-OC-AVE                PIC 9(5)V99.
    05 WS-OC-Qty                BINARY-LONG.
    05 WS-OC-Total-NUM          BINARY-LONG.

01  WS-Starz                    PIC X(44) VALUE ALL '*'.

01  WS-Vendor-Counters.
    05 WS-VC-AVE                PIC 9(5)V99.
    05 WS-VC-Qty                BINARY-LONG.
    05 WS-VC-Total-NUM          BINARY-LONG.

REPORT SECTION.
RD  CPU-Report
    CONTROLS ARE FINAL
                 F-SR-Vendor-TXT
                 F-SR-Family-TXT

    PAGE LIMIT IS    36 LINES
        HEADING      1
        FIRST DETAIL 5
        LAST DETAIL  36.

01  TYPE IS PAGE HEADING.
    05 LINE NUMBER PLUS 1.
       10 COL 1  SOURCE WS-Date                PIC 9999/99/99.
       10 COL 14 VALUE 'CPU Benchmark Scores'.
       10 COL 37 VALUE 'Page:'.
       10 COL 43 SOURCE PAGE-COUNTER           PIC Z9.
    05 LINE NUMBER PLUS 1.
       10 COL 1  SOURCE WS-Starz               PIC X(44).
    05 LINE NUMBER PLUS 1.
       10 COL 1  VALUE '**'.
       10 COL 6  VALUE 'All CPU Data From cpubenchmark.net'.
       10 COL 43 VALUE '**'.
    05 LINE NUMBER PLUS 1.
       10 COL 1  SOURCE WS-Starz               PIC X(44).

01  TYPE CONTROL HEADING F-SR-Family-TXT.
    05 LINE NUMBER PLUS 1.
       10 COL 1  SOURCE F-SR-Vendor-TXT        PIC X(6).
       10 COL 8  SOURCE F-SR-Family-TXT        PIC X(7).
    05 LINE NUMBER PLUS 1.
       10 COL 1  VALUE 'Family'.
       10 COL 9  VALUE 'Model'.
       10 COL 16 VALUE 'Benchmark Score (High to Low)'.
    05 LINE NUMBER PLUS 1.
       10 COL 1  VALUE '======'.
       10 COL 9  VALUE '======'.
       10 COL 16 VALUE '============================='.

01  Detail-Line TYPE IS DETAIL.
    05 LINE NUMBER PLUS 1.
       10 COL 1  SOURCE F-SR-Family-TXT PIC X(7) GROUP INDICATE.
       10 COL 9  PIC X(6)       SOURCE F-SR-Model-TXT.
       10 COL 16 PIC ZZZZ9      SOURCE F-SR-Score-NUM.

01  End-Family TYPE IS CONTROL FOOTING F-SR-Family-TXT.
    05 LINE NUMBER PLUS 1.
       10 COL 9                 VALUE  'Ave...'.
       10 COL 16 PIC ZZZZ9.99   SOURCE WS-FC-AVE.
       10 COL 25                VALUE  '('.
       10 COL 26 PIC ZZ9        SUM    WS-One-Const.
       10 COL 30                VALUE  'Family CPUs)'.

01  End-Vendor TYPE IS CONTROL FOOTING F-SR-Vendor-TXT.
    05 LINE NUMBER PLUS 1.
       10 COL 9                 VALUE  'Ave...'.
       10 COL 16 PIC ZZZZ9.99   SOURCE WS-VC-AVE.
       10 COL 25                VALUE  '('.
       10 COL 26 PIC ZZ9        SUM    WS-One-Const.
       10 COL 30                VALUE  'Vendor CPUs)'.

01  End-Overall TYPE IS CONTROL FOOTING FINAL.
    05 LINE NUMBER PLUS 1.
       10 COL 9                 VALUE  'Ave...'.
       10 COL 16 PIC ZZZZ9.99   SOURCE WS-OC-AVE.
       10 COL 25                VALUE  '('.
       10 COL 26 PIC ZZ9        SUM    WS-One-Const.
       10 COL 30                VALUE  'CPUs)'.

PROCEDURE DIVISION.
DECLARATIVES.
000-End-Family SECTION.
    USE BEFORE REPORTING End-Family.
1.  IF WS-FC-Qty > 0
        COMPUTE WS-FC-AVE = WS-FC-Total-NUM / WS-FC-Qty
    ELSE
        MOVE 0 TO WS-FC-AVE
    END-IF
    MOVE 0 TO WS-FC-Qty
              WS-FC-Total-NUM
    .
000-End-Vendor SECTION.
    USE BEFORE REPORTING End-Vendor.
1.  IF WS-VC-Qty > 0
        COMPUTE WS-VC-AVE = WS-VC-Total-NUM / WS-VC-Qty
    ELSE
        MOVE 0 TO WS-VC-AVE
    END-IF
    MOVE 0 TO WS-VC-Qty
              WS-VC-Total-NUM
    .
000-End-Overall SECTION.
    USE BEFORE REPORTING End-Overall.
1.  IF WS-OC-Qty > 0
        COMPUTE WS-OC-AVE = WS-OC-Total-NUM / WS-OC-Qty
    ELSE
        MOVE 0 TO WS-OC-AVE
    END-IF
    MOVE 0 TO WS-OC-Qty
              WS-OC-Total-NUM
    .
END DECLARATIVES.

010-Main SECTION.
1.  ACCEPT WS-Date FROM DATE YYYYMMDD
    SORT SORT-FILE
        ASCENDING KEY    F-SR-Vendor-TXT
                         F-SR-Family-TXT
        DESCENDING KEY   F-SR-Score-NUM
        ASCENDING KEY    F-SR-Model-TXT
        INPUT PROCEDURE  100-Pre-Process-Data
        OUTPUT PROCEDURE 200-Generate-Report
    STOP RUN
    .
100-Pre-Process-Data SECTION.
1.  OPEN INPUT CPU-FILE
    PERFORM FOREVER
        READ CPU-FILE
        AT END
            EXIT PERFORM
        END-READ
        MOVE SPACES TO SORT-REC
        UNSTRING CPU-REC DELIMITED BY ','
            INTO F-SR-Score-NUM,
                 F-SR-Vendor-TXT,
                 F-SR-Family-TXT,
                 F-SR-Model-TXT
        RELEASE SORT-REC
    END-PERFORM
    CLOSE CPU-FILE
    .
200-Generate-Report SECTION.
1.  INITIALIZE WS-Family-Counters
               WS-Flags
    OPEN OUTPUT REPORT-FILE
    INITIATE CPU-Report
    RETURN SORT-FILE
    AT END
        MOVE 'Y' TO WS-F-EOF
    END-RETURN
    PERFORM UNTIL WS-F-EOF = 'Y'
        GENERATE Detail-Line
        ADD 1              TO WS-FC-Qty
                              WS-OC-Qty
                              WS-VC-Qty
        ADD F-SR-Score-NUM TO WS-FC-Total-NUM
                              WS-OC-Total-NUM
                              WS-VC-Total-NUM
        RETURN SORT-FILE
        AT END
            MOVE 'Y' TO WS-F-EOF
        END-RETURN
    END-PERFORM
    TERMINATE CPU-Report
    CLOSE REPORT-FILE
    .


7.6.3. Generated Report Pages

Finally, here’s the report the program generates!

2013/12/24   CPU Benchmark Scores   Page:  1
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
AMD    A10
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
A10     6800K   5062
        5800B   4798
        6700    4767
        5800K   4677
        5700    4251
        4657M   3449
        5750M   3332
        5757M   3253
        4600M   3145
        5745M   2758
        4655M   2505
        Ave...  3817.90 ( 11 Family CPUs)
AMD    A4
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
A4      6300    2305
        5300    2078
        5150M   1973
        5000    1919
        3420    1768
        4300M   1685
        5300B   1632
        3400    1625
        3300    1583
        3330MX  1343
        3310MX  1263
        3300M   1237
        3305M   1227
        3320M   1193
____________________________________________

2013/12/24   CPU Benchmark Scores   Page:  2
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
A4      4355M   1169
        1200     677
        1250     559
        Ave...  1484.47 ( 17 Family CPUs)
AMD    A6
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
A6      3670    3327
        3650    3232
        3620    2892
        3600    2798
        5200    2440
        6400K   2384
        3430MX  2277
        5400K   2174
        3410MX  2101
        3420M   2078
        3500    1995
        3400M   1964
        5350M   1958
        5400B   1906
        5357M   1878
        1450    1634
        4400M   1630
        4455M   1296
        Ave...  2220.22 ( 18 Family CPUs)
AMD    A8
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
A8      6600K   4719
        6500    4390
        5600K   4348
____________________________________________

2013/12/24   CPU Benchmark Scores   Page:  3
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
A8      5500    4052
        3870K   3682
        3850    3552
        5500B   3464
        3820    3217
        3800    3215
        5550M   3052
        5557M   2935
        3550MX  2866
        4500M   2709
        5545M   2434
        3510MX  2426
        3530MX  2276
        3520M   2245
        4555M   2193
        3500M   2050
        Ave...  3148.68 ( 19 Family CPUs)
AMD    FX
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
FX      9590   10479
        9370    9807
        8350    9067
        8320    8131
        8150    7719
        6350    7017
        8140    6845
        8120    6605
        6300    6388
        6200    6194
        8100    6163
        6120    5813
____________________________________________

2013/12/24   CPU Benchmark Scores   Page:  4
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
FX      6100    5421
        4350    5247
        4170    4774
        4300    4711
        4130    4153
        4150    4094
        4100    4055
        Ave...  6457.00 ( 19 Family CPUs)
        Ave...  3448.86 ( 84 Vendor CPUs)
Intel  Core i3
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
Core i3 4340    5117
        4330    5115
        4130    4904
        3250    4757
        3245    4414
        3225    4407
        3240    4259
        3220    4219
        4130T   4041
        3210    3820
        3240T   3793
        3220T   3724
        3130M   3655
        4000M   3443
        3120M   3301
        3110M   3076
        3227U   2575
        4010U   2459
        3217U   2266
        4010Y   2003
____________________________________________

2013/12/24   CPU Benchmark Scores   Page:  5
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
Core i3 3229Y   1885
        Ave...  3677.76 ( 21 Family CPUs)
Intel  Core i5
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
Core i5 4670K   7565
        4670    7492
        3570K   7118
        4570    7061
        3570    6993
        3550    6828
        4570S   6803
        3570S   6709
        3550S   6631
        3470    6576
        4440    6517
        4570R   6474
        3450    6442
        4670T   6351
        3340    6282
        4430    6282
        3350P   6199
        3470S   6077
        3450S   6071
        3475S   5991
        4430S   5954
        3330    5902
        3335S   5781
        3330S   5690
        3570T   5414
        3340S   5372
        4330M   4804
____________________________________________

2013/12/24   CPU Benchmark Scores   Page:  6
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
Core i5 4300M   4786
        4288U   4663
        3470T   4591
        3380M   4555
        4258U   4381
        4200M   4333
        3340M   4327
        3360M   4314
        3320M   4101
        3230M   3995
        4300U   3917
        3210M   3807
        4350U   3604
        3427U   3589
        4250U   3482
        3437U   3479
        4200U   3355
        3337U   3280
        3317U   3126
        3439Y   3057
        4570T   2503
        4210Y   2382
        4200Y   2358
        3339Y   2252
        4300Y   1743
        Ave...  5026.13 ( 52 Family CPUs)
Intel  Core i7
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
Core i7 4960X  14291
        4930K  13620
        3970X  12823
____________________________________________

2013/12/24   CPU Benchmark Scores   Page:  7
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
Core i7 3960X  12718
        3930K  12107
        4960HQ 10262
        4770K  10190
        4771   10078
        4770    9969
        4820K   9969
        4770S   9803
        4930MX  9754
        3770K   9578
        3770    9420
        4850HQ  9331
        4900MQ  9323
        3920XM  9196
        3770S   9074
        3940XM  9052
        3840QM  9025
        3820    8995
        4770T   8803
        4800MQ  8567
        3820QM  8548
        3740QM  8512
        3720QM  8347
        3770T   8280
        4700HQ  8161
        4750HQ  8066
        4702HQ  8002
        4700MQ  7946
        3630QM  7759
        4702MQ  7647
        3610QM  7532
        4765T   7367
____________________________________________

2013/12/24   CPU Benchmark Scores   Page:  8
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
Core i7 4700EQ  7352
        3615QM  7310
        3632QM  7055
        3612QE  6988
        3612QM  6907
        3635QM  6516
        3610QE  6144
        3615QE  5495
        4600M   4892
        3540M   4861
        3520M   4588
        4558U   4507
        4600U   4484
        4650U   4345
        3687U   4271
        3667U   4032
        3555LE  4009
        4500U   3992
        3537U   3912
        3517U   3701
        4610Y   3680
        3689Y   3479
        3517UE  3449
        Ave...  7725.58 ( 58 Family CPUs)
        Ave...  6005.16 (131 Vendor CPUs)
        Ave...  5006.42 (215 CPUs)





____________________________________________


7.7. Control Hierarchy (Revisited)

The sample program just discussed presents a great opportunity to show what can happen if you don’t define the control hierarchy of a report properly.

I changed the "CONTROLS ARE" clause on the sample program from this:

CONTROLS ARE FINAL
             F-SR-Vendor-TXT
             F-SR-Family-TXT

To this:

CONTROLS ARE FINAL
             F-SR-Family-TXT
             F-SR-Vendor-TXT

And then ran the report again. Here are the first two pages of that new report. See what happened to the control breaks?

2013/12/24   CPU Benchmark Scores   Page:  1
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
AMD    A10
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
A10     6800K   5062
        5800B   4798
        6700    4767
        5800K   4677
        5700    4251
        4657M   3449
        5750M   3332
        5757M   3253
        4600M   3145
        5745M   2758
        4655M   2505
        Ave...  3817.90 ( 11 Vendor CPUs)
        Ave...  3817.90 ( 11 Family CPUs)
AMD    A4
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
A4      6300    2305
        5300    2078
        5150M   1973
        5000    1919
        3420    1768
        4300M   1685
        5300B   1632
        3400    1625
        3300    1583
        3330MX  1343
        3310MX  1263
        3300M   1237
        3305M   1227
____________________________________________

2013/12/24   CPU Benchmark Scores   Page:  2
********************************************
**   All CPU Data From cpubenchmark.net   **
********************************************
A4      3320M   1193
        4355M   1169
        1200     677
        1250     559
        Ave...  1484.47 ( 17 Vendor CPUs)
        Ave...  1484.47 ( 17 Family CPUs)
AMD    A6
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
A6      3670    3327
        3650    3232
        3620    2892
        3600    2798
        5200    2440
        6400K   2384
        3430MX  2277
        5400K   2174
        3410MX  2101
        3420M   2078
        3500    1995
        3400M   1964
        5350M   1958
        5400B   1906
        5357M   1878
        1450    1634
        4400M   1630
        4455M   1296
        Ave...  2220.22 ( 18 Vendor CPUs)
        Ave...  2220.22 ( 18 Family CPUs)
AMD    A8
Family  Model  Benchmark Score (High to Low)
======  ====== =============================
A8      6600K   4719
____________________________________________


7.8. Turning PHYSICAL Page Formatting Into LOGICAL Formatting

You can trick RWCS into using the PAGE LIMIT values as logical specifications rather than physical ones quite easily — simply include an ASCII form-feed (X’0C’) character into your page heading design! Here’s how the sample program shown earlier could be easily modified:

Simply Change This…

01  TYPE IS PAGE HEADING.
    05 LINE NUMBER 1.
       10 COL 1  SOURCE WS-Date PIC 9999/99/99.
       10 COL 14 VALUE 'CPU Benchmark Scores'.
       10 COL 37 VALUE 'Page:'.
       10 COL 43 SOURCE PAGE-COUNTER PIC Z9.
    05 LINE NUMBER PLUS 1.
       10 COL 1  SOURCE WS-Starz PIC X(44).
    05 LINE NUMBER PLUS 1.
       10 COL 1  VALUE '**'.
       10 COL 6  VALUE 'All CPU Data From ' &
                       'cpubenchmark.net'.
       10 COL 43 VALUE '**'.
    05 LINE NUMBER PLUS 1.
       10 COL 1  SOURCE WS-Starz PIC X(44).

To This…

01  TYPE IS PAGE HEADING.
    05 LINE NUMBER 1.                          *> NEW
       10 COL 1  VALUE X’0C’.                  *> NEW
    05 LINE NUMBER PLUS 1.                     *> CHANGED
       10 COL 1  SOURCE WS-Date PIC 9999/99/99.
       10 COL 14 VALUE 'CPU Benchmark Scores'.
       10 COL 37 VALUE 'Page:'.
       10 COL 43 SOURCE PAGE-COUNTER PIC Z9.
    05 LINE NUMBER PLUS 1.
       10 COL 1  SOURCE WS-Starz PIC X(44).
    05 LINE NUMBER PLUS 1.
       10 COL 1  VALUE '**'.
       10 COL 6  VALUE 'All CPU Data From ' &
                       'cpubenchmark.net'.
       10 COL 43 VALUE '**'.
    05 LINE NUMBER PLUS 1.
       10 COL 1  SOURCE WS-Starz PIC X(44).

RWCS will still be counting lines to decide when to close off one page and start a new one, but when a new page is started it’s page heading will physically form-feed the printer when the report is printed. As long as any printer you plan on using supports at least as many physical print lines as what is defined as the "PAGE LIMIT" value in whatever paper orientation and font you plan on (or are limited to) printing in, you have now divorced your program from the physical realities of the printer!

Of course, whatever software you are using to deliver the printed document to the printer with must allow the ASCII form-feed character to pass through to the printer.


8. Interfacing With The OS



8.1. Compiling Programs

Program source files should have extensions of ".cob" or ".cbl".

Program file names should match exactly the specification of PROGRAM-ID (including case).

Spaces cannot be included in primary entry-point names and therefore should not be included in program file names.

The GnuCOBOL compiler will translate your COBOL program into C source code, compile that C source code into executable binary form using the "C" compiler specified when GnuCOBOL was built and link that executable binary into:

Directly executable form

This is an executable file directly-executable from the command-line. On Windows computers, this would be an ".exe" file. On Unix systems, this will be a file with no specific extension, but with execute permissions. This file will include the main program as well as any static-linked subprograms.

Static-linkable form

This is a single subprogram compiled into object-code form, ready to be linked in with a main program to form a directly-executable program. On windows computers, these generally are ".o" (object-code) files.

Dynamically-loadable executable form

These are dynamically-loadable object code files ready to be invoked from other programs at execution time. On Windows systems, these would be ".dll" files, while on Unix systems they are typically ".so" files (OSX uses ".dylib").



8.1.1. cobc - The GnuCOBOL Compiler

The GnuCOBOL compiler is named "cobc" ("cobc.exe" on a Windows system).

The following describes the syntax and option switches of the cobc command. This information may be displayed by entering the command "cobc –help" or "cobc -h".

Usage: cobc [options]... file...

Options:
  -h, -help             display this help and exit
  -V, -version          display compiler version and exit
  -i, -info             display compiler information (build/environment)
  -v, -verbose          display compiler version and the commands
                        invoked by the compiler
  -vv, -verbose=2       like -v but additional pass verbose option
                        to assembler/compiler
  -vvv, -verbose=3      like -vv but additional pass verbose option
                        to linker
  -q, -brief            reduced displays, commands invoked not shown
  -###                  like -v but commands not executed
  -x                    build an executable program
  -m                    build a dynamically loadable module (default)
  -j [<args>], -job[=<args>]
                        run program after build, passing <args>
  -std=<dialect>        warnings/features for a specific dialect
                        <dialect> can be one of:
                        cobol2014, cobol2002, cobol85, default,
                        ibm, mvs, bs2000, mf, acu;
                        see configuration files in directory config
  -F, -free             use free source format
  -fixed                use fixed source format (default)
  -O, -O2, -Os          enable optimization
  -g                    enable C compiler debug / stack check / trace
  -d, -debug            enable all run-time error checking
  -o <file>             place the output into <file>
  -b                    combine all input files into a single
                        dynamically loadable module
  -E                    preprocess only; do not compile or link
  -C                    translation only; convert COBOL to C
  -S                    compile only; output assembly file
  -c                    compile and assemble, but do not link
  -T <file>             generate and place wide program listing into <file>
  -t <file>             generate and place a program listing into <file>
  --tlines=<lines>      specify lines per page in listing, default = 55
  --tsymbols            specify symbols in listing
  -P[=<dir or file>]    generate preprocessed program listing (.lst)
  -Xref                 specify cross reference in listing
  -I <directory>        add <directory> to copy/include search path
  -L <directory>        add <directory> to library search path
  -l <lib>              link the library <lib>
  -A <options>          add <options> to the C compile phase
  -Q <options>          add <options> to the C link phase
  -D <define>           define <define> for COBOL compilation
  -K <entry>            generate CALL to <entry> as static
  -conf=<file>          user-defined dialect configuration; see -std
  -list-reserved        display reserved words
  -list-intrinsics      display intrinsic functions
  -list-mnemonics       display mnemonic names
  -list-system          display system routines
  -save-temps[=<dir>]   save intermediate files
                        - default: current directory
  -ext <extension>      add file extension for resolving COPY

  -W                    enable all warnings
  -Wall                 enable most warnings (all except as noted below)
  -Wno-<warning>        disable warning enabled by -W or -Wall
  -Wno-unfinished       do not warn if unfinished features are used
                        - ALWAYS active
  -Wno-pending          do not warn if pending features are mentioned
                        - ALWAYS active
  -Wobsolete            warn if obsolete features are used
  -Warchaic             warn if archaic features are used
  -Wredefinition        warn incompatible redefinition of data items
  -Wconstant            warn inconsistent constant
  -Woverlap             warn overlapping MOVE items
  -Wpossible-overlap    warn MOVE items that may overlap depending on