This manual documents GNU COBOL 2.1, 23NOV2013 build.

GNU-COBOL Copyright 2002-2007 Keisuke Nishida
          Copyright 2007-2012 Roger While
          Copyright 2013-2013 Ron Norman (RWCS for GNU COBOL)
Document  Copyright 2009-2014 Gary L. Cutler

     Permission is granted to copy, distribute and/or modify this
     document under the terms of the GNU Free Documentation License
     [FDL], Version 1.3 or any later version published by the Free
     Software Foundation; with Invariant Section "Introduction", no
     Front-Cover Texts, and no Back-Cover Texts.  A copy of the license
     is included in the section entitled "GNU Free Documentation
     License".

GNU COBOL Programmer's Guide
****************************

This manual documents the 23NOV2013 build of GNU COBOL 2.1.

List of Chapters and Appendices:

Full Contents:

1. Introduction
***************

This document describes the syntax, semantics and usage of the COBOL
programming language as implemented by the current version of GNU
COBOL, formerly known as OpenCOBOL.

The principal developers of GNU COBOL are Keisuke Nishida and Roger
While.  They may be contacted through the GNU COBOL website -
sourceforge.net/projects/open-cobol.

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

1.1. Additional Reference Sources
=================================

For those wishing to learn COBOL for the first time, I can strongly
recommend the following resources.

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
======================

If you already know a programming language, and that language isn't
COBOL, chances are that language is Java, C or C++.  You will find
COBOL a much different programming language than those; sometimes those
differences are a good thing and sometimes they aren't.  The thing to
remember about COBOL is this -- it was designed to solve business
problems.

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
---------------------------------

Despite statements from industry "insiders", the COBOL programming
language is not dead, even though newer and so-called "modern"
languages like Java, C#, .NET, Ruby on Rails and so on appear to have
become the languages of choice in the Information Technology world.
These languages have become popular because they address the following
desired requirements for "modern" programming:

  1. They conform to the principles of Object-Oriented Programming
     (OOP).  This is desired for one major reason -- it facilitates
     "code reusability", 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. smartphones) up to the most
     massive of supercomputers.

     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.

  3. 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:

   * Using programs that, for the most part, are much more
     self-documenting than would be the case with any other programming
     language.

   * Effortlessly providing arithmetic accuracy to 31 digits, with
     performance approaching that of well-written assembly-language
     programs.  Don't think this isn't critically important to banks,
     investment houses and any business interested in tracking
     revenues, expenses and profits (duh - like ALL of them).

   * Integrating well with non-COBOL infrastructures such as XML, SOA,
     MQ, almost any DBMS, Transaction Processing platforms,
     Queue-Management facilities and other programming languages.

   * By running on almost as many different computing platforms as Java
     can.  You can't run COBOL programs in your smartphone, but
     desktops, workstations, midframes/servers, mainframes and
     supercomputers are all fair game.

Today's IT managers and business leaders are faced with a challenging
dilemma -- how do you maintain the enourmous COBOL codebase 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 favor 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 favor of (presumably) less-expensive
     "open systems" (midframe/server) solutions.

     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.

  2. 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 pidgeon-holed into a
     niche technology is a factor inhibiting many of today's
     programmers from willingly volunteering for such training.

  3. By moving the user-interface onto the desktop; such efforts
     involve running modern-language front-end clients on user desktops
     (or laptops or smartphones, etc.) with COBOL programs provideing
     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
codebase 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 GNU
COBOL -- another implementation of COBOL in addition to those mentioned
earlier.  The distinguishing characteristic of GNU COBOL versus those
others is that GNU COBOL is open-source and therefore FREE.  It is
community-enhanced and community-supported.  Later in this document
(see So What is GNU COBOL?), you'll begin to learn more about this
COBOL implementation's capabilities.

1.2.2. Programmer Productivity
------------------------------

Throughout the history of computer programming, the search for new ways
to improve of the productivity of programmers has been a major
consideration.  Other than hobbyists, programming is an activity
performed for money, and businesses abhor spending anything more than
is absolutely necessary; even government agencies try to spend as
little money on projects as is absolutely necessary.

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:

   * The development of so-called "higher-level" programming languages
     that enable a programmer to specify in a single statement of the
     language an action that would have required many more separate
     statements in a prior programming language.  The standardization
     of such languages, making them usable on a wide variety of
     computers and operating systems, was a key aspect of this
     development.  COBOL was a pioneering development in this area,
     being a direct descendant of the very first higher-level language
     (FLOW-MATIC, developed by US Naval Lieutenant Grace Hopper) and
     the first to become standardized.

   * The establishment of programming techniques that make programs
     easier to read and therefore easier to understand.  Not only do
     such techniques reduce the amount of rework necessary simply to
     make a program work as designed, but they also reduce the amount
     of time a programmer needs to study an existing program in order
     how to best adapt it to changing business requirements.  The
     foremost development in this area was structured programming.
     Introduced in the late 1970s, this approach to programming spawned
     new programming languages (PASCAL, ALGOL, PL/1 and so forth)
     designed around it.  With the ANSI85 standard, COBOL embraced the
     principles espoused by structured programming mavens as well as
     any of the languages designed strictly around it.

   * The establishment of programming techniques AND the introduction
     of programming language capabilities to facilitate the reusability
     of program code.  Anything that supports code reusability can have
     a profound impact to the amount of time it takes to develop new
     applications or to make significant changes to existing ones.  In
     recent years, object-oriented programming (OOP) has been the
     industry "poster child" for code reusability.  By enabling program
     logic and the data structures that logic manipulates to be
     encapsulated into easily stored and retrieved (and therefore
     "reusable") modules called classes, the object-oriented languages
     such as Java, C++ and C# have become the favorites of academia.
     Since students are being trained in these languages and only
     these, by and large, it's no surprise that -- today --
     object-oriented programming languages are the darlings of the
     industry.

     The reality is, however, that good programmers have been
     practicing code reusability for more than a half-century.  Up
     until recently, COBOL programmers have had some of the best code
     reusability tools available -- they've been doing it with
     copybooks and subprograms rather than classes, methods and
     attributes but the net results have been similar.  With the
     COBOL2002 standard and proposed COBOL20xx standard, the COBOL
     programming language has become just as "object-oriented" as the
     "modern" languages, while preserving the ability to support,
     modify, compile and execute "legacy" COBOL programs as well.

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

1.3. So What is GNU COBOL?
==========================

GNU COBOL is an open source COBOL compiler and runtime environment,
written using the C programming language.  GNU COBOL is typically
distributed in source-code form, and must then be built for your
computer's operating system using the system's C compiler and loader.
While originally developed for the UNIX and Linux operating systems,
GNU COBOL has also been successfully built for OSX computers or Windows
computers utilizing the UNIX-emulation features of such tools as Cygwin
and MinGW.

The MinGW approach is a personal favorite with the author of this
manual because it creates a GNU COBOL compiler and runtime library that
require only a single MinGW DLL to be available for the GNU COBOL
compiler, runtime library and user programs.  That DLL is freely
distributable under the terms of the GNU General Public License.  A
MinGW build of GNU COBOL 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 GNU COBOL
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.

GNU COBOL 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 GNU COBOL 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").

GNU COBOL fully supports much of the ANSI85 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
------------------------------

COBOL programs consist of a sequence of words and symbols.  Words,
which consist of sequences of letters (upper- and/or lower-case),
digits, dashes ("-") and/or underscores ("_") may have a pre-defined,
specific, meaning to the compiler or may be invented by the programmer
for his/her purposes.

The GNU COBOL language specification defines over 700 'Reserved Words' --
words to which the compiler assigns a special meaning.

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.

See Appendix B - Reserved Word List, for a complete list of GNU
COBOL reserved words.

1.3.2. User-Defined Words
-------------------------

When you write GNU COBOL programs, you'll need to create a variety of
words to represent various aspects of the program, the program's data
and the external environment in which the program will run.  This will
include internal names by which data files will be referenced, data
item names and names of executable logic procedures.

User-defined words may be composed from the characters "A" through "Z"
(upper- and/or lower-case), "0" through "9", dash ("-") and underscore
("_").  User-defined words may neither start nor end with hyphen or
underscore characters.

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
-------------------------

All COBOL implementations allow the use of both upper and lowercase
letters in program coding.  GNU COBOL is completely insensitive to the
case used when writing reserved words or user-defined names.  Thus,
"AAAAA", "aaaaa", "Aaaaa" and "AaAaA" are all the same word as far as
GNU COBOL is concerned.

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 UPPERCASE 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
------------------------------

The most vociferous critics of COBOL frequently focus on the wordiness
of the language, often citing the case of a so-called "Hello World"
program as the "proof" that COBOL is so much more tedious to program in
than more "modern" languages.  This tedium is cited as such a
significant impact to programmer productivity that, in their opinions,
COBOL can't go away quickly enough.

Here are two different "Hello World" applications -- one written in
Java and the second in GNU COBOL.  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 GNU COBOL:

    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:

   * Many systems have program-development tools available to ease the
     task of coding programs; those tools that concentrate on COBOL are
     capable of providing templates for much of the "overhead" verbiage
     of any program...

   * Good programmers have -- for decades -- maintained their own
     skeleton "template" programs for a variety of program types;
     simply load a template into a text editor and you've got a good
     start to the program...

   * Legend has it that there's actually only been ONE program ever
     written in COBOL, and all programs ever "written" thereafter were
     simply derivatives of that one.  Although this is clearly intended
     as a (probably) bad joke, it is nevertheless close to the very
     simple truth that many programers"reuse" existing COBOL programs
     when creating new ones.  There's certainly nothing preventing this
     from happening with programs written in other languages, but it
     does seem to happen more in COBOL shops.  It's ironic that "code
     reusability" is one of the arguments used to justify the existence
     of the "modern" languages.

1.3.5. Divisions Organize Programs
----------------------------------

COBOL programs are structured into four major areas of coding, each
with its own purpose.  These four areas are known as divisions.

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
----------------

A 'Copybook' is a segment of program code that may be utilized by
multiple programs simply by having those programs use the "COPY"
statement (see COPY) to import that code.  This code may define
files, data structures or procedural code.

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
----------------------

A contiguous area of storage within the memory space of a program that
may be referenced, by name, in a COBOL program is referred to as a
'Data Item'.  Other programming languages use the term variable,
property or attribute to describe the same thing.

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'.  For example, a
35-character 'Employee-Name' group item might consist of a 20-character
'Last-Name' followed by a 14-character 'First-Name' and a 1-character
'Middle-Initial'.

A data item that isn't itself formed from other data items is referred
to in COBOL as an 'Elementary Item'.  In the previous example,
'Last-Name', 'First-Name' and 'Middle-Initial' are all elementary
items.

1.3.8. Files
------------

One of COBOLs strengths is the wide variety of data files it is capable
of accessing.  GNU COBOL programs, like those created with other COBOL
implementations, need to have the structure of any files they will be
reading and/or writing described to them.  The highest-level
characteristic of a file's structure is defined by specifying the
organization of the file, as follows:

"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) GNU COBOL 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 thru 99
     first.

     When the file is written to by a GNU COBOL 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 GNU COBOL 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 GNU COBOL 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 GNU COBOL 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 thru 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
     behavior.  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
     contaoin 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 GNU COBOL 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 GNU COBOL 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 GNU
     COBOL 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 GNU COBOL
     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 GNU COBOL
     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 (btree), an elaborate hash
     structure or something else is pretty much irrelevant to the
     programmer -- the behavior 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 GNU COBOL
     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 GNU COBOL 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 GNU COBOL 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
---------------------

Other programming languages have arrays, COBOL has tables.  They're
basically the same thing.  There are two special statements that exist
in the COBOL language -- "SEARCH" (see SEARCH) and "SEARCH ALL"
(see SEARCH ALL) -- that make finding data in a table easy.

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
--------------------------------

The COBOL language includes a powerful "SORT" statement (see SORT)
that can sort large amounts of data according to arbitrarily complex
key structures.  This data may originate from within the program or may
be contained in one or more external files.  The sorted data may be
written automatically to one or more output files or may be processed,
record-by-record in the sorted sequence.

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
------------------------------------

There have been programming languages designed specifically for the
processing of text strings, and there have been programming languages
designed for the sole purpose of performing high-powered numerical
computations.  Most programming languages fall somewhere in the
middle.

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

Concatenate two or more strings:

   * "CONCATENATE" intrinsic function (see CONCATENATE).

   * "STRING" statement (see STRING).

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

   * "LOCALE-TIME" intrinsic function (see LOCALE-TIME).

   * "LOCALE-DATE" intrinsic function (see LOCALE-DATE).

Convert a binary value to its corresponding character in the program's
characterset:

   * "CHAR" intrinsic function (see CHAR).  Add 1 to argument
     before invoking the function; the description of the "CHAR"
     intrinsic function presents a technique utilizing the "MOVE"
     statement that will accomplish the same thing without the need of
     adding 1 to the numeric argument value first.

Convert a character string to lower-case:

   * "LOWER-CASE" intrinsic function (see LOWER-CASE).

   * "C$TOLOWER" built-in system subroutine (see C$TOLOWER).

   * "CBL_TOLOWER" built-in system subroutine (see CBL_TOLOWER).

Convert a character string to upper-case:

   * "UPPER-CASE" intrinsic function (see UPPER-CASE).

   * "C$TOUPPER" built-in system subroutine (see C$TOUPPER).

   * "CBL_TOUPPER" built-in system subroutine (see CBL_TOUPPER).

Convert a character string to only printable characters:

   * "C$PRINTABLE" built-in system subroutine (see C$PRINTABLE).

Convert a character to its numeric value in the program's
characterset:

   * "ORD" intrinsic function (see ORD).  Subtract 1 from the
     result; the description of the "ORD" intrinsic function presents a
     technique utilizing the "MOVE" statement that will accomplish the
     same thing without the need of adding 1 to the numeric argument
     value first.

Count occurrences of substrings in a larger string:

   * "INSPECT" statement (see INSPECT) with the "TALLYING" clause.

Decode a formatted numeric string back to a numeric value:

   * "NUMVAL" intrinsic function (see NUMVAL).

   * "NUMVAL-C" intrinsic function (see NUMVAL-C).

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

   * "LENGTH" intrinsic function (see LENGTH).

   * "BYTE-LENGTH" intrinsic function (see BYTE-LENGTH).

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

   * Use of a reference modifier on the string field - see Reference Modifiers.

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:

   * "MOVE" statement (see MOVE) with picture-symbol editing
     applied to the receiving field:

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

   * "C$JUSTIFY" built-in system subroutine (see C$JUSTIFY).

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

   * "INSPECT" statement (see INSPECT) with the "CONVERTING".

   * "TRANSFORM" statement (see TRANSFORM).

   * "SUBSTITUTE" intrinsic function (see SUBSTITUTE).

   * "SUBSTITUTE-CASE" intrinsic function (see SUBSTITUTE-CASE).

Parse a string, breaking it up into substrings based upon one or more
delimiting character sequences(1):

   * "UNSTRING" statement (see UNSTRING).

Removal of leading or trailing spaces from a string:

   * "TRIM" intrinsic function (see TRIM).

Substitution of a single substring with another of the same length,
based upon the substrings starting character position and length:

   * "MOVE" statement (see MOVE) with a reference modifier on the
     "receiving" field (see Reference Modifiers).

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

   * "INSPECT" statement (see INSPECT) with a "REPLACING" clause.

   * "SUBSTITUTE" intrinsic function (see SUBSTITUTE).

   * "SUBSTITUTE-CASE" intrinsic function (see SUBSTITUTE-CASE).

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

   * "SUBSTITUTE" intrinsic function (see SUBSTITUTE).

   * "SUBSTITUTE-CASE" intrinsic function (see SUBSTITUTE-CASE).

---------- Footnotes ----------

(1) These delimiters may be single characters, multiple-character
strings or multiple consecutive occurrences of either

1.3.12. Screen Formatting Features
----------------------------------

The COBOL2002 standard formalizes extensions to the COBOL language that
allow for the definition and processing of text-based screens, as is a
typical function on mainframe and midframe computers as well as on many
point-of-sale (i.e. "cash register") systems.  GNU COBOL implements
virtually all the screen-handling features described by COBOL2002.

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 GNU COBOL, 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 GNU COBOL programs, with
a moderate research time investment (Tcl/Tk, for example) -- but none
are currently included with GNU COBOL.

1.3.12.1. A Sample Screen
.........................

A Sample Screen Produced by a GNU COBOL Program:

================================================================================
 GCic (2014/01/02 11:24) GNU COBOL 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 GNU COBOL Interactive Compiler, or
GCic.  See GCic (gnucobsp.info), 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
............................................

GNU COBOL 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 GNU COBOL 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
     nams defined in screenio.cpy, are as follows:

       0. Black: COB-COLOR-BLACK

       1. Blue: COB-COLOR-BLUE

       2. Green: COB-COLOR-GREEN

       3. Cyan (Turquoise): COB-COLOR-CYAN

       4. Red: COB-COLOR-RED

       5. Magenta: COB-COLOR-MAGENTA

       6. Yellow: COB-COLOR-YELLOW

       7. White: COB-COLOR-WHITE

Text Brightness

     There are three possible brightness levels supported for text --
     lowlight (dim), normal and highlight (bright).  Not all GNU COBOL
     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 GNU COBOL run-time library when the GNU COBOL
     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 GNU COBOL.  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 propcessed by the program.  If no such
     character is defined for an input field, an underscore ("_") will
     be assumed.

See Colors (gnucobsp.info), for a source and cross-reference
listing of a program (Colors.cbl) that can be used to display a test
screen illustrating all available video formatting options.

1.3.13. Report Writer Features
------------------------------

GNU COBOL includes an implementation of the Report Writer Control
System, or RWCS.  This is a standardized, optional add-on feature to
the COBOL language which automates much of the mechanics involved in
the generation of printed reports by:

  1. Controlling the pagination of reports, including:

       A. The automatic production of a one-time notice on the first
          page of the report (report heading).

       B. The production of zero or more header lines at the top of
          every page of the report (page heading).

       C. The production of zero or more footer lines at the bottom of
          every page of the report (page footing).

       D. The automatic numbering of printed pages.

       E. The formatting of those report lines that make up the main
          body of the report (detail).

       F. 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.

       G. 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:

       A. 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.

       B. Automatically causing suppressed detail group-indicate fields
          to re-appear should a detail group be printed on a new page.

       C. 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 summarization, as follows:

       A. Automatically generating subtotals in control and/or report
          footings, summarizing values of any fields in the detail
          group.

       B. 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
---------------------------

There are three ways in which data division data gets initialized.

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

        * Alphanumeric and alphabetic (i.e. text) data items will be
          initialized to "SPACES".

        * Numeric data items will be initialized to a value of "ZERO".

        * Data items with an explicit "VALUE" (see VALUE) clause in
          their definition will be initialized to that specific value.

     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 GNU
     COBOL's default initialization rules won't prove disruptive.

  2. A programmer may use the "INITIALIZE" statement (see
     INITIALIZE) to intitialize 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
----------------------------------

Syntax of the GNU COBOL language will be described in special "syntax
diagrams" using the following syntactical-description techniques:

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

     Reserved words of the COBOL language will appear in UPPERCASE.
     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 lowercase 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 metacharacters 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 metacharacters 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 "|" metacharacters.

| 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 ... metacharacter sequence signifies that the syntax element
     immediately preceeding 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 ({}) metacharacters 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 "..."
     metacharacters.

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

     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 metacharacter
     sequence described above.

1.3.16. Format of Program Source Lines
--------------------------------------

Prior to the COBOL2002 standard, source statements in COBOL programs
were structured around 80-column punched cards.  This means that each
source line in a COBOL program consisted of five different "areas",
defined by their column number(s).

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' and 'Free Format Mode' are
used to refer to these two modes of source code formatting.

The GNU COBOL 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 to start
     in Fixed Format Mode (remember that this is the default) or the
     "-free" switch to start in Free Format Mode.

  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 GNU COBOL 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 GNU
COBOL source line record when the compiler is operating in Fixed Format
Mode.  Remember that this is the default mode for the GNU COBOL
compiler.

1-6 - Sequence Number Area

     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 - Indicator Area

     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 GNU COBOL 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 GNU COBOL will honor 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 - Area "A"

     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 - Area "B"

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

73-80 - Program Name Area

     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 GNU COBOL) 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 GNU COBOL 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' (major groupings of
sections, paragraphs and descriptive or procedural coding that all
relate to a common purpose), named Identification, Environment, Data
and Procedure.

  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

        * The "IDENTIFICATION DIVISION." header is always optional.

  3. The following points pertain to the environment division:

        * If both optional sections of this division are coded, they
          must be coded in the sequence shown.

        * Each of these sections consists of a series of specific
          paragraphs ("SOURCE-COMPUTER" and "OBJECT-COMPUTER", for
          example).  Each of these paragraphs serves a specific
          purpose.  If no code is required for the purpose one of the
          paragraphs serves, the entire paragraph may be omitted.

        * If none of the paragraphs within one of the sections are
          coded, the section header itself may be omitted.

        * The paragraphs within each section may only be coded in that
          section, but may be coded in any order.

        * If none of the sections within the environment division are
          coded, the "ENVIRONMENT DIVISION." header itself may be
          omitted.

  4. The following points pertain to the data division:

        * The data division consists of six optional sections -- when
          used, those sections must be coded in the order shown in the
          syntax diagram.

        * Each of these sections consists of code which serves a
          specific purpose.  If no code is required for the purpose one
          of those sections serves, the entire section, including it's
          header, may be omitted.

        * If none of the sections within the data division are coded (a
          highly unlikely, but theoretically possible circumstance),
          the "DATA DIVISION." header itself may be omitted.

  5. The following points pertain to the procedure division:

        * As with the other divisions, the procedure division may
          consist of sections and those sections may -- in turn --
          consist of paragraphs.  Unlike the other divisions, however,
          section and paragraph names are defined by the programmer,
          and there may not be any defined at all if the programmer so
          wishes.

        * Each Event-Handler-Routine will be a separate section devoted
          to trapping a particular run-time event.  If there are no
          such sections coded, the "DECLARATIVES." and "END
          DECLARATIVES." lines may be omitted.

  6. A single file of COBOL source code may contain:

        * A portion of a program; these files are known as copybooks

        * A single program.  In this case, the "END PROGRAM" or "END
          FUNCTION" statement is optional.

        * Multiple programs, separated from one another by "END
          PROGRAM" or "END FUNCTION" statements.  The final program in
          such a source code file need not have an "END PROGRAM" or
          "END FUNCTION" statement.

  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 GNU COBOL source
     file, only a single output executable program will be generated
     from that source file when the file is compiled.

1.3.18. Comments
----------------

The following information describes how comments may be imbedded into
GNU COBOL program source to provide documentation.

Comment Type  Source Mode -- Description
-------------------------------------------------------------------
Blank Lines   FIXED -- Blank lines may be inserted as desired.

              FREE -- Blank lines may be inserted as desired.

Full-line     FIXED -- An entire source line will be treated as a
comments      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     FIXED -- An entire source line will be treated as a
comments      comment by coding a slash ("/") in column seven
with          (7).  Many COBOL compilers will also issue a
form-feed     form-feed in the program listing so that the "/"
              line is at the top of a new page.  The GNU COBOL
              compiler does not support this form-feed behavior.

              The GNU COBOL Interactive Compiler, or GCic, does
              support this form-feed behavior when it generates
              program source listings!  See GCic (gnucobsp.info),
              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  FIXED -- Any text following the character sequence
comments      "*>" 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      FIXED -- By coding a "D" in column 7 (upper- or
that may be   lower-case), an otherwise valid GNU COBOL source
treated as    line will be treated as a comment by the compiler.
code,
typically     FREE -- By specifying the character sequence ">>D"
for           (upper- or lower-case) as the first non-blank
debugging     characters on a source line, an otherwise valid GNU
purposes      COBOL source line will be treated as a comment by
              the compiler.

              Debugging statements may be compiled either by
              specifying the "-fdebugging-line" switch on the GNU
              COBOL compiler or by adding the "WITH DEBUGGING
              MODE" clause to the "SOURCE-COMPUTER" paragraph.

1.3.19. Literals
----------------

Literals are constant values that will not change during the execution
of a program.  There are two fundamental types of literals -- numeric
and alphanumeric.

1.3.19.1. Numeric Literals
..........................

A numeric literal is a numeric constant which may be used as an array
subscript, as a value in arithmetic expressions, or in any procedural
statement where a numeric value may be used.  Numeric literals may take
any of the following forms:

   * Integers such as 1, 56, 2192 or -54.

   * Non-integer fixed point values such as 1.317 or -2.95.

   * Floating-point values using "Enn" notation such as 9.92E25,
     representing 9.92 x 10^25 (10 raised to the 25th power) or
     5.7E-14, representing 5.7 x 10^-14 (10 raised to the -14th power).
     Both the mantissa (the number before the E) and the exponent (the
     number after the E) may be explicitly specified as positive (with
     a +), negative (with a -) or unsigned (and therefore implicitly
     positive).  A floating-point literal's value must be within the
     range -1.7 x 10^308  to +1.7 x 10^308 with no more than 15 decimal
     digits of precision.

   * Hexadecimal numeric literals such as H"1F" (31 decimal), h'22' (34
     decimal) or H'DEAD' (57005 decimal).  The H character may either
     be upper- or lower-case and either single quote (') or
     double-quote (") characters may be used in a hexadecimal literal,
     provided both aren't used in the same literal.  Hexadecimal
     numeric literals are limited to a maximum of sixteen hexadecimal
     digits (a 64-bit value).

1.3.19.2. Alphanumeric Literals
...............................

An alphanumeric literal is a character string suitable for display on a
computer screen, printing on a report, transmission through a
communications connection or storage in alphanumeric or alphabetic data
items.

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 GNU
COBOL 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:

   * A sequence of characters enclosed by a pair of single-quote (') or
     double-quote (") characters constitutes a string literal.  The
     double-quote character (") may be used as a data character within
     an apostrophe-delimited string literal, and an apostrophe may be
     used as a data character within a double-quote-delimited string
     literal.  If an apostrophe character must be included as a data
     character within an apostrophe-delimited string literal, express
     that character as two consecutive apostrophes (").  If a
     double-quote character must be included as a data character within
     a double-quote-delimited string litaral, express that character as
     two consecutive double-quotes ("").

   * A literal formed according to the same rules as for a string
     literal (above), but prefixed with the letter "Z" (upper- or
     lower-case) constitutes a zero-delimited string literal.  These
     literals differ from ordinary string literals in that they will be
     explicitly terminated with a byte of hexadecimal value 00.  These
     'Zero-Delimited Alphanumeric Literals' are easily passable to C
     subprograms, as this is the convention C uses to store character
     strings.

   * A 'Hexadecimal Alphanumeric Literal' such as X"4A4B4C" (4A4B4C16 =
     the ASCII string 'JKL'), x'20' (an ASCII space) or X'30313233'
     (3031323316 = the ASCII string '0123').  The "X" character may
     either be upper- or lower-case and either single quote (') or
     double-quote (") characters may be used.  These hexadecimal
     alphanumeric literals should always consist of an even number of
     hexadecimal digits, because each character is represented by eight
     bits worth of data (2 hex digits).  Hexadecimal alphanumeric
     literals may be of almost unlimited length.

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 (-) coded in the indicator area (column 7).  Here is an
     example (the scale is just for column number reference):

              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.".

  2. Regardless of whether the compiler is operating in Fixed or Free
     Format Mode, GNU COBOL 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 "&" characters.  No
     continuation indicator is needed.  Here's an example:

              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
..............................

Figurative constants are reserved words that may be used as literals
anywhere the figurative constant's value could be interpreted as an
arbitrarily long sequence of the characters in question.  When a
specific length is required, such as would be the case with an argument
to a subprogram, a figurative constant may not be used.  Thus, the
following are valid uses of 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 GNU COBOL 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 characterset the program is using
     (typically, this is the ASCII characterset).  "LOW-VALUES" is a
     synonym of "LOW-VALUE".

     When the characterset in use is ASCII with no collating sequence
     modifications, the "LOW-VALUES" figurative constant value is the
     ASCII "NUL" character.  Because charactersets 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 characterset
     the program is using (typically, this is the ASCII characterset).
     "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
-------------------

A comma (",") or a semicolon (";") may be inserted into a GNU COBOL
program to improve readability at any spot where white space would be
legal, except of course within alphanumeric literals (unless you
actually mean for those characters to be part of the alphanumeric
literal's value).  These characters are always optional.

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 (".") is used to terminate statements in the
identification, environment and data divisions and sentences in the
procedure division.  Syntax diagrams describing code in the first three
divisions will explicitly show where periods need to occur.

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 GNU COBOL 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:

        * As part of the "FROM" clause of a "WRITE" (see WRITE) or
          "RELEASE" statement (see RELEASE).

        * As part of the "TIMES" clause of a "PERFORM" statement (see
          PERFORM).

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 GNU
COBOL's case, the "CALL" facility is powerful enough to be tailored to
the point where a GNU COBOL program can communicate with operating
system, database management and run-time library APIs, even if they
weren't written in COBOL themselves.  See GNU COBOL Main Programs CALLing C Subprograms,
for an example of how a GNU COBOL program
could invoke a C-language subprogram, passing information back and
forth between the two.

The fact that GNU COBOL 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 GNU COBOL program.

2. CDF - Compiler Directing Facility
************************************

The Compiler Directing Facility, or CDF, is a means of controlling the
compilation of GNU COBOL programs.  CDF provides a mechanism for
dynamically setting or resetting certain compiler switches, introducing
new source code from one or more source code libraries, making dynamic
source code modifications and conditionally processing or ignoring
source statements altogether.  This is accomplished via a series of
special CDF statements and directives that will appear in the program
source code.

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 GNU COBOL -- 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. 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" clause (with or without the optional
     "PRINTING" reserved word) is valid syntactically but is
     non-functional.  It is supported to facilitate compatibility with
     source code written for other versions of COBOL.

  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 imbedded "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" clause allows for one or more of either
     of the following kinds of text replacements to be made:

    <<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 preceeds 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") or end ("TRAILING") of reserved or
          user-defined words.  For example, to change all words of the
          form "0100-xxxxxx" to "020-xxxxxx", code "LEADING ==0100-==
          BY ==020-==".  To simply remove all "0100-" prefixes from
          words, code "LEADING ==0100-== BY ====".

2.2. 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 GNU COBOL 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:

       A. Format 1 of the "REPLACE" statement can be used to make
          changes to program source code in much the same way as the
          "REPLACING" option of the "COPY" statement can, via these
          options:

         <<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 preceeds 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") or end ("TRAILING")
               of reserved or user-defined words.  For example, to
               change all words of the form "0100-xxxxxx" to
               "020-xxxxxx", code "LEADING ==0100-== BY ==020-==".  To
               simply remove all "0100-" prefixes from words, code
               "LEADING ==0100-== BY ====".

       B. 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.

       C. 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.

       D. When a Format 1 "REPLACE" statement with the "ALSO" keyword
          is encountered without Replace Mode being currently active,
          the effect will be as if the "ALSO" had not been specified.
          If Replace Mode already was in effect, the effect will be to
          "push" the current change specification(s) onto the top of a
          stack and add the specification(s) of the new statement to
          those that were already in effect.

       E. 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.

       F. 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:

       A. If Replace Mode is currently inactive, the Format 2 REPLACE
          statement will be ignored.

       B. 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.

       C. 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.3. >>DEFINE
=============

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

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

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

Use the ">>DEFINE" CDF directive to create CDF variables and
(optionally) assign them either literal or environment variable
values.

  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 GNU COBOL
     user-defined names, and may not duplicate any CDF reserved word.
     CDF variable names may duplicate COBOL reserved words, provided
     the "CONSTANT" option is not specified, but such names are not
     recommended.

  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" option is
     used to create a variable without assigning it any value.

  6. The "PARAMETER" option is used to create a variable whose value is
     that of the environment variable of the same name.  Note that this
     value assignment occurs at compilation time, not program execution
     time.

  7. In the absence of the "OVERRIDE" option, <cdf-variable-1> must not
     yet have been defined.  When the "OVERRIDE" option is specified,
     <cdf-variable-1> will be created with the specified value, if it
     had not yet been defined.  If it had already been defined, it will
     be redefined with the new value.

2.4. >>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")
             ~~~~~

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

The ">>IF" CDF directive causes the GNU COBOL compiler to process or
ignore COBOL source statements, CDF text-manipulation statements and/or
CDF directives depending upon the value of one or more conditional
expressions based upon CDF variables.

  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" directive.

  3. There may be any number of ">>ELIF" clauses following an ">>IF",
     including zero.

  4. There may no more than one ">>ELSE" clause following an ">>IF".
     When ">>ELSE" is used, it must follow the ">>IF" and all ">>ELIF"
     clauses.

  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:

       A. 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.

       B. 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.

       C. 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.

       D. 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>>:

       A. The "DEFINED" option tests for whether <cdf-variable-1> has
          been defined, but not yet assigned a value (">>DEFINE ...
          OFF"); use the "NOT" option to test for the variable not
          being defined.

       B. The "SET" option tests for whether <cdf-variable-1> has been
          given a value, either via a ">>SET" statement or via a
          ">>DEFINE" without the "OFF" option.

       C. 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 GNU COBOL "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.

       D. The "<>" symbol stands for "NOT EQUAL TO".

2.5. >>SET
==========

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

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

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

The ">>SET" CDF directive provides an alternate means of performing the
actions of the ">>DEFINE" and ">>SOURCE" directives, as well as a means
of controlling the compiler's "-free" switch, "-fixed" switch and
"-ffold-copy" switch from within program source code.

  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" option provides the equivalent of specifying
     the compiler "-ffold-copy=xxx" switch, where "xxx" is either
     "UPPER" or "LOWER".

  4. The "NOFOLDCOPYNAME" option turns off the effect of either the
     ">>SET FOLDCOPYNAME" statement or the compiler "-ffold-copy=xxx"
     switch.

  5. If the "CONSTANT" option is used, <literal-1> must also be used.
     This option provides another means of defining constants that may
     be used anywhere in the program that a literal could be
     specified.

  6. The remaining options of the ">>SET" CDF directive provide
     equivalent functionality to the ">>DEFINE" and ">>SOURCE"
     directives, as follows:

       A. ">>SET <cdf-variable-1>" == ">>DEFINE <cdf-variable-1> AS
          OFF"

       B. ">>SET <cdf-variable-1> AS <literal-1>" == ">>DEFINE
          <cdf-variable-1> AS <literal-1>"

       C. ">>SET CONSTANT <cdf-variable-1> AS <literal-1>" == ">>DEFINE
          CONSTANT <cdf-variable-1> AS <literal-1>"

       D. ">>SET SOURCEFORMAT AS FIXED" == ">>SOURCE FORMAT IS FIXED"

       E. ">>SET SOURCEFORMAT AS FREE" == ">>SOURCE FORMAT IS FREE"

2.6. >>SOURCE
=============

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

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

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

The ">>SOURCE" CDF directive puts the compiler into "FIXED" or "FREE"
source-code format mode.  This, in effect, provides yet another
mechanism for controlling the compiler's "-free" switch and "-fixed"
switch.

  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.7. >>TURN
===========

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

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

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

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

3. IDENTIFICATION DIVISION
**************************

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

 [ IDENTIFICATION DIVISION. ]
   ~~~~~~~~~~~~~~ ~~~~~~~~
 { PROGRAM-ID.  } program-id [ AS literal-1 ] [ Type-Clause ] .
 { ~~~~~~~~~~   }
 { FUNCTION-ID. }
   ~~~~~~~~~~~
 [ AUTHOR. comment-1. ]
   ~~~~~~
 [ DATE-COMPILED. comment-2. ]
   ~~~~~~~~~~~~~
 [ DATE-WRITTEN. comment-3. ]
   ~~~~~~~~~~~~
 [ INSTALLATION. comment-4. ]
   ~~~~~~~~~~~~
 [ REMARKS. comment-5. ]
   ~~~~~~~
 [ SECURITY. comment-6. ]
   ~~~~~~~~

The "AUTHOR", "DATE-COMPILED", "DATE-WRITTEN", "INSTALLATION", "REMARKS" and
"SECURITY" paragraphs are supported by GNU COBOL only to provide
compatibility with programs written for the ANS1974 (or earlier)
standards.  As of the ANS1985 standard, these clauses have become
obsolete and should not be used in new programs.

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

                      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" is specified.
     If one is coded, either "COMMON", "COMMON INITIAL" or "COMMON
     RECURSIVE" must be specified.

  4. While the actual "IDENTIFICATION DIVISION" header is optional, the
     "PROGRAM-ID" / "FUNCTION-ID" paragraphs are not; only one or the
     other, however, may be coded.

  5. The compiler's "-Wobsolete" switch will cause the GNU COBOL
     compiler to issue warnings messages if these (or any other
     obsolete syntax) is used in a program.

  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:

       A. "COMMON" should be used only within subprograms that are
          nested subprograms.  A nested subprogram declared as "COMMON"
          may be called from any nested program in the source file
          being compiled, not just those "above" it in the nesting
          structure.

       B. The "RECURSIVE" clause, if any, will cause the compiler to
          generate different object code for the subprogram that will
          enable it to invoke itself and to properly return back to the
          program that invoked it.

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

       C. The "INITIAL" clause, if specified, guarantees the subprogram
          will be in its initial (i.e. compiled) state each and every
          time it is executed, not just the first time.

4. ENVIRONMENT DIVISION
***********************

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

   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... . ]
   ~~~~~~~~~~~

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

This division defines the external computer environment in which the
program will be operating.  This includes defining any files that the
program may be .

   * If both optional sections of this division are coded, they must be
     coded in the sequence shown.

   * The paragraphs within the sections may be coded in any order.

   * These sections consist of a series of specific, pre-defined,
     paragraphs ("SOURCE-COMPUTER" and "OBJECT-COMPUTER", for example),
     each of which serves a specific purpose.  If no code is required
     for the purpose one of the paragraphs serves, the entire paragraph
     may be omitted.

   * If any of the paragraphs within one of the sections are coded, the
     section header itself must be coded.

   * If none of the paragraphs within one of the sections are coded,
     the section header itself may be omitted.

   * If none of the sections within the environment division are coded,
     the "ENVIRONMENT DIVISION." header itself may be omitted.

4.1. CONFIGURATION SECTION
==========================

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

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

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

This section defines the computer system upon which the program is
being compiled and executed and also specifies any special
environmental configuration or compatibility characteristics.

  1. The four paragraphs in this section may be specified in any
     order.

  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 ] .
 ~~~~~~~~~~~~~~~                       ~~~~~~~~~ ~~~~

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

This paragraph defines the computer upon which the program is being
compiled and provides one way in which debugging code imbedded within
the program may be activated.

  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 GNU COBOL 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" clause, if present, will inform the compiler
     that debugging lines (those with a "D" in column 7 if Fixed Source
     Mode is in effect, or those prefixed with a ">>D" if Free Source
     Mode is in effect) -- normally treated as comments -- are to be
     compiled.

  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 to the GNU COBOL
     compiler.

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" and "SEGMENT-LIMIT" clauses are syntactically
recognized but are otherwise non-functional.

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

This paragraph describes the computer upon which the program will
execute.

  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 GNU
     COBOL 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" clause allows you to specify a customized
     character collating sequence to be used when alphanumeric values
     are compared to one another.  Data will still be stored in the
     characterset native to the computer, but the logical sequence in
     which characters are ordered for comparison purposes can be
     altered from that defined by the computer's native characterset.
     The <alphabet-name-1> you specify needs to be defined in the
     "SPECIAL-NAMES" (see SPECIAL-NAMES) paragraph.

  6. If no "COLLATING SEQUENCE" clause is specified, the collating
     sequence implied by the characterset native to the computer
     (usually ASCII) will be used.

  7. The optional "CLASSIFICATION" clause may be used to specify a
     locale for the environment in which the program will be executing,
     for the purpose of influencing the uppercase and lowercase
     mappings of characters for the "UPPER-CASE" (see UPPER-CASE)
     and "LOWER-CASE" (see LOWER-CASE) intrinsic functions and the
     classification of characters for the "ALPHABETIC",
     "ALPHABETIC-LOWER" and "ALPHABETIC-UPPER" class tests.  The
     definitions of these classes will be taken from the cultural
     convention specification ("LC_CTYPE") from the specified locale.

     The meanings of the four locale specifications are as follows:

       A. <locale-name-1> references a "LOCALE" (see SPECIAL-NAMES)
          definition.

       B. The keyword "LOCALE" refers to the current locale (in effect
          at the time the program is executed)

       C. The keyword "USER-DEFAULT" references the default locale
          specified for the user currently executing this program.

       D. 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 characterset (ASCII, EBCDIC, ...).

4.1.3. 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             ~~~~~~~~~        }
               ~~~ ~~~~~~~~~

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

The REPOSITORY paragraph provides a way to control access to the
various built-in intrinsic functions and any user defined functions
that your program will be using.

  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" clause allows you to flag one or more (or "ALL")
     built-in intrinsic functions as being usable without the need to
     code the keyword "FUNCTION" in front of the function names.

  3. As an alternative to using the "ALL INTRINSIC" clause, you may
     instead compile your GNU COBOL programs using the
     "-fintrinsics=ALL" switch.

  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.1.4. 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" and "SCREEN CONTROL" clauses are syntactically
recognized but are otherwise non-functional.

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

         <<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" clause allows a decimal integer,
     representing a series of ON/OFF switch settings, to be associated
     with a mnemonic name which may then be coded on a "CALL" statement
     (see CALL).  The switch settings defined by this mnemonic will
     then control how the linkage to a subroutine invoked by the "CALL"
     statement that references <mnemonic-name-1> will be handled.

  6. The "CONSOLE IS CRT" clause, if specified, will cause a "DISPLAY"
     statement lacking an explict "UPON" clause to be treated as a
     "DISPLAY screen-data-item" statement (see DISPLAY screen-data-item),
     and any "ACCEPT" statement lacking a "FROM"
     clause to be treated as a "ACCEPT screen-data-item" statement
     (see ACCEPT screen-data-item).

  7. If the "CRT STATUS" clause is not specified, an implicit
     "COB-CRT-STATUS" identifier (with a "PICTURE 9(4)") will be
     allocated for the purpose of receiving screen "ACCEPT" statuses.
     If "CRT STATUS" is specified, then <identifier-1> must be defined
     in the program as a "PICTURE 9(4)" field.

  8. The "CURRENCY SIGN" clause may be used to redefine the character
     to be used as a currency sign in a "PICTURE" (see PICTURE)
     clause.  The default currency sign is a dollar-sign ($).  You may
     specify any character except "0"-"9", "A"-"Z", "a"-"z", "+", "-",
     ",", ".", "*", "/", ";", "(", ")", "=", "\", quote (") or space.

  9. The "CURSOR IS" clause allows you to specify a 4- or 6-character
     data item into which the cursor screen location at the time a
     screen "ACCEPT" is satisfied.  The value will be returned as rrcc
     or rrrccc, depending upon the length of the specified
     <identifier-2>, where rr and rrr represent the row number
     (starting at zero) and cc and ccc represent the column number
     (also starting at zero).  There is no default data item allocated
     for this data if the "CURSOR IS" clause is not specified, and it
     is the programmer's responsibility to define <identifier-2> if the
     clause is specified.

 10. The "DECIMAL POINT IS COMMA" clause reverses the definition of the
     "," and "." characters when they are used as "PICTURE" editing
     symbols and within numeric literals.  This can have unwanted
     side-effects - see Punctuation.

 11. The "LOCALE" clause may be used to associate external OS-defined
     locale names (<literal-2>) with an internal name (<locale-name-1>)
     that may then be referenced within the program.  Locale names are
     defined by the Operating System and/or C compiler GNU COBOL will
     be utilizing on your computer.

 12. The following is the list of possible locale codes, for example,
     that would be available on a Windows computer running a GNU COBOL
     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" specification causes all
     signed numeric "USAGE DISPLAY" data items to be created as if the
     "SIGN IS TRAILING SEPARATE CHARACTER" clause was included in their
     definitions.

 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 GNU COBOL device name <mnemonic-name-2>.  The list of
     device names built-into GNU COBOL, 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 GNU COBOL 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 GNU COBOL 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 GNU COBOL 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 GNU COBOL shows that this too results in a
     formfeed being issued.

4.1.4.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}...    }
                ~~~~

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

The "ALPHABET" clause provides a means for relating a name to a
specified character code set or collating sequence, including those you
define yourself using the <literal-1> option.

  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. GNU COBOL considers "ASCII", "STANDARD-1" and "STANDARD-2" to be
     interchangeable.

  4. "NATIVE" specifies the system default characterset.

  5. The following points apply to using the <literal-n> specifications
     to compose a custom characterset:

       A. The <literal-n> values are either integers or alphanumeric
          quoted characters.  These represent a single character in the
          "NATIVE" characterset, either by it's actual text value
          (alphanumeric quoted character) or by ordinal position in the
          "NATIVE" characterset (integer),

       B. 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.

       C. 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" characterset.

       D. 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.4.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.4.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 ]
     ~~~

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

The switch-definition clause associates a condition-name with a
run-time execution switch so that the status of that switch may be
tested from within a program.

  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" (n=0-15).

  3. If the program is compiled with the "-fsyntax-extension" switch,
     the switch names "SWn" (n=0-15) are also valid; they correspond to
     "SWITCH-0" through "SWITCH-15", respectively.

  4. At execution time, each switch will be associated with a "COB_SWITCH_n"
     run-time environment variable (see Run Time Environment Variables),
     where "n" will have the value "0" through "15".  Any
     of these sixteen environment variables that have the value "ON"
     (regardless of upper- or lower-case value) will be considered to
     be set "on".  Any of these sixteen environment variables having no
     value at all or a value other than "ON" will be considered "OFF".

  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 GNU COBOL 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" and "OFF STATUS" syntax provides a way of
     associating a condition-name with either the on or off status of
     the switch, so that status may be tested at execution time via the
     "IF" statement (see IF).

4.1.4.4. Symbolic-Characters-Clause
...................................

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

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

   [ IN alphabet-name-1 ]
     ~~

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

This clause may be used to define your own figurative constants.

  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
     characterset 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 characterset).  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.2. INPUT-OUTPUT SECTION
=========================

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

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

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

     [ SAME-RECORD-Statement ]

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

The "INPUT-OUTPUT" section provides for the definition of any files the
program will be accessing as well as control of the I/O buffering
process against those files through the "FILE-CONTROL" and
"I-O-CONTROL" paragraphs, respectively.

  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", "RECORD DELIMITER", "RESERVE" and "ALL OTHER" clauses
are syntactically recognized but are otherwise non-functional.

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

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" clause, to be used only for files that will be used
     to provide input data to the program, indicates the file may or
     may not actually be available at run-time.  Attempts to "OPEN" an
     "OPTIONAL" file when the file does not exist will receive a
     special non-fatal file status value (see status 05 in the list of
     file status values below) indicating the file is not available; a
     subsequent attempt to "READ" that file will return an "AT END"
     (end-of-file) condition.  Optionally, files may be designated as
     "NOT OPTIONAL", if desired.  This is useful when specifying the
     compiler's "-foptional-file" switch, which automatically makes all
     files "OPTIONAL" except for those explicitly declared as "NOT
     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 filesystems
     will be associated with <file-name-1>, as follows:

       A. 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>).

       B. "ASSIGN TO DISC '<file-name-1>'" will be assumed if there is
          no "ASSIGN" clause on a "SELECT".

       C. If an "ASSIGN" clause is coded without a <<Device>>, the
          device "DISC" will be assumed.

       D. If a <<Locator>> clause is coded, the COBOL file
          <file-name-1> will be attached to a data file within any
          filesystem 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:

            a. If <literal-1> is coded, the value of the literal will
               serve as the File Location String that will identify the
               data file.

            b. If <identifier-1> is coded, the value of the identifier
               will serve as the File Location String that will
               identify the data file.

            c. 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
               progrem opens <file-name-1> will then serve as the File
               Location String that will identify the data file.

            d. File Location Strings will be discussed shortly.

       E. 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:

            a. "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.

            b. "DISPLAY" will assume an attachment to the "STDOUT"
               logical device; these files should only be used for
               output.

            c. "KEYBOARD" will assume an attachment to the "STDIN"
               logical device; these files should only be used for
               input.

            d. "PRINTER" will assume an attachment to the "LPT1"
               logical device/port; these files should only be used for
               output.

            e. "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.

       F. 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).

       G. 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.

       H. If the compiler "config" file you used to compile the program
          with had a "filename-mapping" value of "yes", the GNU COBOL
          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:

            a. 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 behavior
               for every config file except "ibm".

            b. 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
               theform "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.

            c. 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 GNU COBOL 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.

       I. 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.

       J. Paths and filenames 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" or "SORT STATUS" clause (they are both
     equivalent and only one or the other, if any, should be specified)
     is used to specify the name of a two-digit numeric data item into
     which an I/O status code will be saved after every I/O verb that
     is executed against the file.  This does not actually allocate the
     data item -- you must define the item yourself somewhere in the
     data division.

     Possible status codes that can be returned to a "FILE STATUS" data
     item are as follows:

     Code Explanation
     ---------------------------------------------------------------------
     00   Success
     02   Success (Duplicate Record Key Written)
     05   Success (Optional File Not Found)
     07   Success (No Unit)
     10   End of file reached if reading forward or beginning-of-file
          reached if reading backward
     14   Out of key range
     21   Key invalid
     22   Attempt to duplicate key value
     23   Key not found
     30   Permanent I/O error
     31   Inconsistent filename
     34   Boundary violation
     35   File not found
     37   Permission denied
     38   Closed with lock
     39   Conflicting attribute
     41   File already open
     42   File not open
     43   Read not done
     44   Record overflow
     46   Read 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)
     51   Record locked
     52   End of page
     57   "LINAGE" specifications invalid
     61   File sharing failure
     91   File not available

  8. The "SHARING" clause defines the conditions under which the
     program will be willing (or not) to allow other programs executing
     at the same time to access the file.  See File Sharing, for
     the details.

  9. The "LOCK" clause defines how concurrent access to the file will
     be managed on a record-by-record basis.  See Record Locking,
     for the details.

 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 ]
      ~~~~~~         ~~~~~~~~~~

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

Files declared as "ORGANIZATION SEQUENTIAL" will consist of records
with no explicit end-of-record delimiter character sequences; records
in such files are "delineated" by a calculated byte-offset (based on
the maximum record length) into the file.

  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 imbed 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" clause is optional because, if
     absent, it will be assumed anyway for this type of file.  The
     internal structure of these files is such that they can only be
     processed in a sequential manner; in order to read the 100th
     record in such a file, for example, you first must read records 1
     through 99.

  8. Sequential files are processed using the following statements:

        * "CLOSE" (see CLOSE)

        * "COMMIT" (see COMMIT)

        * "DELETE" (see DELETE)

        * "MERGE" (see MERGE)

        * "OPEN" (see OPEN)

        * "READ" (see READ)

        * "REWRITE" (see REWRITE)

        * "SORT" (see SORT)

        * "UNLOCK" (see UNLOCK)

        * "WRITE" (see WRITE)

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.

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

Files declared as "ORGANIZATION LINE SEQUENTIAL" will consist of
records terminated by an end-of-record delimiter character or character
sequence.

  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 GNU COBOL (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" clause is optional because, if
     absent, it will be assumed anyway for this type of file.  The
     internal structure of these files is such that the data can only
     be processed in a sequential manner; in order to read the 100th
     record in such a file, for example, you first must read records 1
     through 99.

 10. Files assigned to "PRINTER" or "CONSOLE" should be specified as
     "ORGANIZATION LINE SEQUENTIAL".

 11. Line Sequential files are processed using the following
     statements:

        * "CLOSE" (see CLOSE)

        * "COMMIT" (see COMMIT)

        * "DELETE" (see DELETE)

        * "MERGE" (see MERGE)

        * "OPEN" (see OPEN)

        * "READ" (see READ)

        * "REWRITE" (see REWRITE)

        * "SORT" (see SORT)

        * "UNLOCK" (see UNLOCK)

        * "WRITE" (see WRITE)

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 ]
      ~~~~~~~~

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

These files are files with an internal organization such that records
may be processed in a sequential manner based upon their physical
location in the file or in a random manner by allowing records to be
read, written or updated by specifying the relative record number in
the file.

  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" clause is optional only if "ACCESS MODE
     SEQUENTIAL" is specified.

  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" means that records will be processed in
     random sequence by specifying their record number in the file
     every time the file is read or written.

  9. "ACCESS MODE DYNAMIC" indicates the program may switch back and
     forth between "SEQUENTIAL" and "RANDOM" mode during execution.
     The file starts out initially in "SEQUENTIAL" mode when first
     opened but the program may use the "START" statement (see
     START) to switch between sequential and random access.

 10. The "RELATIVE KEY" data item is a numeric data item that cannot be
     defined as a field within records of this file.  Its purpose is to
     return the current relative record number of a relative file that
     is being processed in "SEQUENTIAL" access mode and to serve as a
     key that specifies the relative record number to be read or
     written when processing a relative file in "RANDOM" access mode.

 11. Relative files are processed using the following statements:

        * "CLOSE" (see CLOSE)

        * "COMMIT" (see COMMIT)

        * "DELETE" (see DELETE)

        * "MERGE" (see MERGE), "ACCESS MODE RANDOM" not allowed

        * "OPEN" (see OPEN)

        * "READ" (see READ)

        * "REWRITE" (see REWRITE)

        * "SORT" (see SORT), "ACCESS MODE RANDOM" not allowed

        * "START" (see START)

        * "UNLOCK" (see UNLOCK)

        * "WRITE" (see WRITE)

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.

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

Indexed files, like relative files, may have their records processed in
either a sequential or random manner.  Unlike relative files, however,
the actual location of a record in an indexed file is calculated
automatically based upon the value(s) of one or more alphanumeric
fields within records of the file.  For example, an indexed file
containing product data might use the product identification code as a
record key.  This means you may read, write or update the "A6G4328"th
record or the "Z8X7723"th record directly, based upon the product id
value of those records!

  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", the default "ACCESS MODE" if none is
     specified,  indicates that the records of the file will be
     processed in a sequential manner with respect to the values of the
     "RECORD KEY" or the "ALTERNATE RECORD KEY" most-recently
     referenced on a "START" statement (see START).

  6. "ACCESS MODE RANDOM" means that records will be processed in
     random sequence by accessing the record with specific record key
     or alternate record key values.

  7. "ACCESS MODE DYNAMIC" allows the file will be processed either in
     "RANDOM" or "SEQUENTIAL" mode; the program may switch between the
     two modes as needed.  The "START" statement is used to make the
     switch between modes.

  8. The "PRIMARY KEY" clause defines the field within the record used
     to provide the primary access to records within the file.  No two
     records in the file will be allowed to have the same "PRIMARY KEY"
     field value.

  9. The "ALTERNATE RECORD KEY" clause, if used, defines an additional
     field within the record that provides an alternate means of
     directly accessing records or an additional field by which the
     file's contents may be processed sequentially.  You have the
     choice of allowing records to have duplicate alternate key values,
     if necessary.

 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:

        * "CLOSE" (see CLOSE)

        * "COMMIT" (see COMMIT)

        * "DELETE" (see DELETE)

        * "MERGE" (see MERGE), "ACCESS MODE RANDOM" not allowed

        * "OPEN" (see OPEN)

        * "READ" (see READ)

        * "REWRITE" (see REWRITE)

        * "SORT" (see SORT), "ACCESS MODE RANDOM" not allowed

        * "START" (see START)

        * "UNLOCK" (see UNLOCK)

        * "WRITE" (see WRITE)

4.2.2. 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.

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

4.2.3. SAME RECORD AREA
-----------------------

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

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

The "SAME SORT-MERGE" and "SAME SORT" clauses are syntactically
recognized but are otherwise non-functional.

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

The "SAME RECORD AREA" clause allows you to specify that multiple files
should share the same input and output memory buffers.

  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.

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        }

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

All data used by any COBOL program must be defined in one of the six
sections of the data division, depending upon the purpose of the data.

  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
===============================

GNU COBOL data items, like those of other COBOL implementations, are
described in a hierarchical manner.  This accommodates the fact that
data items frequently need to be able to be broken up into subordinate
items.  Take for example, the following logical layout of a portion of
a data item named "Employee":

                           Employee
                               |                     Additional
              :----------------:----------------:--> Data Items ...
              |                                 |
        Employee-name                    Employment-Dates
              |                                 |
    :---------:-------------:           :-------:-------:
    |         |             |           |               |
Last-Name First-Name Middle-Initial From-Date        To-Date
                                        |               |
                                   :----:----:     :----:----:
                                   |    |    |     |    |    |
                                 Year Month Day  Year Month Day

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 GNU COBOL, 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 Special Data Items).

So, the definition of these data items in a GNU COBOL 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.  GNU COBOL 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?  Thet'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 GNU COBOL 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".  There may be any number of "FILLER" items defined
within a group item.  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.  Note that it is
possible that the name of the group item itself might be specified as
"FILLER" if there is no need to ever refer directly to the group
structure itself.

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                                       }

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

Every file that has been referenced by a "SELECT" statement (see
SELECT) must also be described in the file section of the data
division.

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", "DATA RECORD", "LABEL RECORD", "RECORDING MODE" and
"VALUE OF" clauses are syntactically recognized but are obsolete and
non-functional.  These clauses should not be coded in new programs.

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

  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" clause allows a custom alphabet, defined in the
     "SPECIAL-NAMES" (see SPECIAL-NAMES) paragraph, to be
     associated with a file. This clause is valid only when used with
     sequential or line sequential files.

  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:

        * "LINES AT TOP" -- the number of unused (i.e. left blank)
          lines at the top of every page.  The default if this if not
          specified is zero.

        * "LINES AT BOTTOM" -- the number of unused (i.e. left blank)
          lines at the bottom of every page.  The default if this if
          not specified is zero.

        * "LINAGE IS n LINES" -- the total number of used/usable lines
          on the page.

        * The sum of the previous three specifications should be the
          total number of possible lines available on one printed
          page.

        * "FOOTING AT" -- the line number beyond which nothing may be
          printed except for any footing that is to appear on every
          page.  The default for this if not specified is zero, meaning
          there will be no footings.  This value cannot be larger than
          the "LINAGE IS n LINES" value.

  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" and "RECORD IS VARYING" clauses are ignored
     (with a warning message issued) when used with line sequential
     files.  With other file organizations, these mutually-exclusive
     clauses define the length of data records within the file.  The
     data item specified as <identifier-6> must be defined within one
     of the record descriptions of <file-name-1>.

 12. The "REPORT IS" clause announces to the compiler that the file
     will be dedicated to the Report Writer Control System (RWCS); the
     clause names one or more reports, each to be described in the
     report section.  The following special rules apply when the
     "REPORT" clause is used:

       A. 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.

       B. 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).

       C. 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
          honored.

 13. The following special rules apply only to sort/merge work files:

       A. Sort/merge work files should be assigned to "DISK" (or
          "DISC") on their "SELECT" statements.

       B. Sorts and merges will be performed in memory, if the amount
          of data being sorted allows.

       C. 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 "TMPDIR" run-time environment variable (see Run Time Environment Variables)

             * The "TMP" run-time environment variable

             * The "TEMP" run-time environment variable

          (in that order)

       D. 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".

       E. 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.

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

Every sort file description ("SD" or "FD") must be followed by at least
one 01-level data item, except for file descriptions containing the
"REPORT IS" clause.  These 01-level data items, in turn, may be broken
down into subordinate group and elementary items.  An 01-level data
item defined here in the file section is also known as a 'Record', even
if it is an elementary item, provided that elementary item lacks the
"CONSTANT" attribute.

  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:

        * Another 01-level item is found -- this signifies the start of
          another record layout for the file.

        * Another "FD" or "SD" is found -- this marks the completion of
          the detailed description of the file and begins another.

        * A division or section header is found -- this also marks the
          completion of the detailed description of the file and
          signifies the end of the file section as well.

  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.

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

The working-storage section is used to describe data items that are not
part of files, screens or reports and whose data values persist
throughout the execution of the program.

  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 "SYNCRONISED" 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:

        * Another 01-level item is found -- this signifies the end of
          the definition of one record and the start of a another.

        * A 77-level item is found -- this signifies the end of the
          definition of the record and begins the definition of a
          special data item; see 77-Level Data Items, for more
          information.

        * A division or section header is found -- this also marks the
          completion of a record and signifies the end of the
          working-storage section as well.

  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 unchangable 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.

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

The local-storage section is similar to working-storage, but describes
data within a subprogram that will be dynamically allocated and
initialized (automatically) each time the subprogram is executed.
See Data Initialization, for the rules of data ititialization.

  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 "SYNCRONISED" 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:

        * Another 01-level item is found -- this signifies the end of
          the definition of one record and the start of a another.

        * A division or section header is found -- this also marks the
          completion of a record and signifies the end of the
          local-storage section as well.

  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 unchangable 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.

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

The linkage section describes data within a subprogram that serves as
either input arguments to or output results from the subprogram.

  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 ""SYNCRONISED"" 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:

        * Another 01-level item is found -- this signifies the end of
          the definition of one record and the start of a another.

        * A division or section header is found -- this also marks the
          completion of a record and signifies the end of the linkage
          section as well.

  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 unchangable 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:

       A. A linkage section should occur only within a subprogram.  The
          compiler will not prevent its use in a main program,
          however.

       B. 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.

       C. 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" and "COLUMNS" clauses are syntactically recognized but
are otherwise non-functional.

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

This section describes the layout of printed reports as well as many of
the functional aspects of the generation of reports that will be
produced via the Report Writer Control System.

  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" clause:

       A. If no "PAGE LIMITS" clause is specified, the entire report
          will be generated as if it consists of a single arbitrarily
          long page.

       B. All literals (<literal-2> through <literal-8>) must be
          numeric with non-zero positive integer values.

       C. All identifiers (<identifier-2> through <identifier-8>) must
          be numeric, unedited with non-zero positive integer values.

       D. 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).

       E. Any value specified for <literal-3>|<identifier-3> will be
          ignored.

       F. The "HEADING" clause defines the first line number at which a
          report heading or page heading may be presented.

       G. The "FIRST DETAIL" clause defines the first line at which a
          detail group may be presented.

       H. The "LAST CONTROL" HEADING clause defines the last line at
          which any line of a control heading may be presented.

       I. The "LAST DETAIL" clause defines the last line at which any
          line of a detail group may be presented.

       J. The "FOOTING" clause defines the last line at which any line
          of a control footing group may be presented.

       K. 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"

       L. 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" clause:

       A. 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".

       B. Include the reserved word "FINAL" if you want to include a
          special control heading before the first detail line is
          generated ("CONTROL HEADING FINAL") or after the last detail
          line is generated ("CONTROL FOOTING FINAL").

       C. If you specify "FINAL", it must be the first control break
          named in the "RD".

       D. Any <identifier-9> specifications included on the "CONTROL"
          clause are referencing data names defined in any data
          division section except for the report section.

       E. There must be a "CONTROL HEADING" and/or "CONTROL FOOTING"
          report group defined in the report section for each
          <identifier-9>.

       F. 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:

       A. 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.

       B. 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 ]...

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

The syntax shown here documents how a report group is defined to a
report.  This syntax is valid only in the report section, and only then
after an "RD".

  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 ]...

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

Data item descriptions describing the report lines and fields that make
up the substance of a report group immediately follow the definition of
that group.

  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" clauses) are frequently used
     to describe entire lines of a report, while elementary items
     (those with a picture clause) are frequently used to describe
     specific fields of information on the report.  When this coding
     convention is being used, group items will have "LINE" (see
     LINE) clauses and no "COLUMN" (see COLUMN) clauses while
     elementary items will be specified the other way around.

  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 ]...

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

The screen section describes the screens to be displayed during
terminal/console I-O.

  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:

        * "AUTO", "AUTO-SKIP" and "AUTOTERMINATE"

        * "BACKGROUND-COLOR" and "BACKGROUND-COLOUR"

        * "BELL" and "BEEP"

        * "FOREGROUND-COLOR" and "FOREGROUND-COLOUR"

        * "FULL" and "LENGTH-CHECK"

        * "REQUIRED" and "EMPTY-CHECK"

        * "SECURE" and "NO-ECHO"

  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 GNU
     COBOL 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" or "LENGTH" options)
     or a literal of the same type as <literal-1> may be used.

  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 GNU COBOL 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 GNU COBOL program that uses 01-level constants
to display the length (in bytes) of the various picture-less usage
types.

    IDENTIFICATION DIVISION.
    PROGRAM-ID. USAGELengths.
    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 GNU COBOL, the"
        DISPLAY "PICTURE-less USAGEs 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 GNU COBOL is:

    On this system, with this build of GNU COBOL, the
    PICTURE-less USAGEs 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 "SYNCRONISED" 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 GNU COBOL 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.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 GNU COBOL 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 lieue 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 behavior depending upon the section in which the clause
     is used, as follows:

       A. 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.

       B. 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, useable 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 GNU COBOL 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") or line
("ERASE EOL") prior to displaying the screen data item.

  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"
File/Sort-Description as being sharable 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:

       A. The "EXTERNAL" clause may only be specified at the 77 or 01
          level.

       B. An "EXTERNAL" item must have a data name and that name cannot
          be "FILLER".

       C. "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 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 GNU COBOL 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 itsm'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 GNU COBOL 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 sharable 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:

       A. The "GLOBAL" clause may only be specified at the 77 or 01
          level.

       B. A "GLOBAL" item must have a data name and that name cannot be
          "FILLER".

       C. "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:

       A. On the first presentation of the detail group following the
          "INITIATE" (see INITIATE) of the report.

       B. On the first presentation of the detail group after every new
          page is started.

       C. 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' behavior 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 behavior 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 behavior 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 JUSTIFIED                  With JUSTIFIED
     ----------------------------------------------------------------------
     01  A PIC X(6).                    01  A PIC X(6) JUSTIFIED RIGHT.
     MOVE "ABC" TO A                    MOVE "ABC" TO A

     Result is 'ABCbbb'                 Result is 'bbbABC'

              When the value is longer than the field size...

     Without JUSTIFIED                  With JUSTIFIED
     ----------------------------------------------------------------------
     01  A PIC X(6).                    01  A PIC X(6) JUSTIFIED RIGHT.
     MOVE "ABCDEFGHI" TO A              MOVE "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 GNU COBOL 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 GNU COBOL 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:

       A. The column location of a report item will be determined by
          the "COLUMN" (see COLUMN) clause.

       B. The value of <integer-1> must be 1 or greater.

       C. 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").

       D. The symbol "+" may be used in lieue 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.

       E. The optional "NEXT PAGE" clause specifies that -- regardless
          of whether or not the report group containing this clause
          could fit on the report page being currently generated, the
          report group will be forced to appear on a new page.

  3. The following points document the use for format 2 of the "LINE"
     clause:

       A. The column location of a screen section field is determined
          by the "COLUMN" (see COLUMN) clause.

       B. The value of <integer-1> must be 1 or greater.

       C. 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.

       D. 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").

       E. The symbol "+" may be used in lieue 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.

       F. 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", "NEXT PAGE" and "PAGE" are interchangeable.

  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" clause can be added to an "OCCURS" to
     create a variable-length table.  In such cases, the value of
     <integer-1> specifies what the minimum number of entries in the
     table will be while <integer-2> specifies the maximum.  Such
     tables will be allocated out to the maximum size specified as
     <integer-2>.  At execution time the value of <identifier-1> will
     determine how many of the table elements are accessible.

  6. See the documentation of the "SEARCH" (see SEARCH), "SEARCH
     ALL" (see SEARCH ALL) and "SORT" (see SORT) statements for
     explanations of the "KEY" and "INDEXED BY" clauses.

  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:

       A. The optional "STEP" clause defines an incrementation value
          that will be added to any absolute "LINE" (see LINE) or
          "COLUMN" (see COLUMN) number specifications that may be
          part of or subordinate to this data item's definition.

       B. The optional "VARYING" clause defines an identifier that may
          be used as a subscript for the multiple occurrences of this
          or any subordinate data item should the "SOURCE" (see
          SOURCE) or "SUM" (see SUM) clause(s) on this or
          subordinate data items reference entries within the table.
          The <identifier-2> data item is dynamically created as needed
          and cannot be referenced outside the scope of the report data
          item definition.

       C. 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 GNU COBOL 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 Characterset'.  Support for national
          charactersets in GNU COBOL is currently only partially
          implemented, and the compile- and run-time effect of using
          the "N" picture symbol is the same as if "X(2)" had been
          coded, with the additional effect that such a field will
          qualify as a "NATIONAL" or "NATIONAL-EDITED" field on an
          "INITIALIZE" (see INITIALIZE) statement.

    "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' while those that use
     "9" picture symbols without any "A" or "X" symbols (or those that
     have a "USAGE" without a "PICTURE") are known as 'Numeric Data
     Items'.  All other data items are referred to as 'Alphanumeric
     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 thru 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' data item.
     Numeric edited data items are treated as alphanumeric and may not
     serve either as table subscripts or as source arguments on an
     arithmetic statement.

 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 meager 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.  GNU COBOL accepts these.  Programmers
     creating GNU COBOL programs should avoid such <picture-string>s if
     there is any liklihood 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. 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:

       A. The level number of both the subject and object data items
          must be the same.

       B. The level numbers of both the subject and object data items
          cannot be 66, 78 or 88.

       C. 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.

       D. 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.

       E. The total allocated size of the subject data item must be the
          same as the total allocated size of the object data item.

       F. 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.

       G. 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.37. 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.38. 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 GNU COBOL implementation was
     built with.  As of this time, the 'PDCurses' package (used for
     native Windows or MinGW builds) does not support "REQUIRED".

5.9.39. 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.40. 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.41. 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" option, the sign of the data
     item's value will be encoded by transforming the last ("TRAILING")
     or first ("LEADING") digit as follows:

     First/Last Digit  Value For         Value for
                       Positive          Negative
     ------------------------------------------------------
     0                 0                 p
     1                 1                 q
     2                 2                 r
     3                 3                 s
     4                 4                 t
     5                 5                 u
     6                 6                 v
     7                 7                 w
     8                 8                 x
     9                 9                 y

  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 imbedded 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 imbedded within the data item's storage
     prevents the data item from being used as a source field in
     arithmetic operations.

5.9.42. 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", "LINE-COUNTER" or a "SUM" (see SUM)
     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.43. 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" option:

       A. 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.

       B. 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.

       C. 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.

       D. 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" option:

       A. 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.

       B. 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 behavior that would be expected.

       C. 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.44. 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:

       A. If the binary item occupies one byte of storage, no
          synchronization is performed.

       B. If the binary item occupies two bytes of storage, the binary
          item is allocated at the next half-word boundary.

       C. If the binary item occupies four bytes of storage, the binary
          item is allocated at the next word boundary.

       D. If the binary item occupies four bytes of storage, the binary
          item is allocated at the next word boundary.

5.9.45. 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 itsm's definition.

5.9.46. 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.47. 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 GNU COBOL 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.48. 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 GNU COBOL.

     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 GNU COBOL

     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" attribute explicitly coded, or
     "DISPLAY", "PACKED-DECIMAL", "COMP-5", "COMP-X" items that do not
     have an "S" symbol in their picture clause cannot preserve
     negative values that may be stored into them.  Storing a negative
     value into such a field will actually result in the sign being
     stripped, essentially saving the absolute value in the data item.

  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 thru F.
     Traditional packed decimal encoding rules call for hecadecimal
     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/GNU COBOL 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 GNU COBOL.

     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. GNU COBOL 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".

     GNU COBOL 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.49. 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 itsm's definition.

5.9.50. 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:

       A. The clauses "VALUE IS" and "VALUES ARE" are interchangeable.

       B. The reserved words "THRU" and "THROUGH" are interchangeable.

       C. See 88-Level Data Items, for a discussion of how this
          format of "VALUE" is used to create condition names.

       D. 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:

       A. 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.

       B. The "VALUE" clause is ignored on "EXTERNAL" (see
          EXTERNAL) data items or on any data items defines as
          subordinate to an "EXTERNAL" data item.

       C. 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.

       D. If the optional "ALL" clause is used, it may only be used
          with an alphanumeric literal value; the value will be
          repeated as needed to completely fill the data item.  Here
          are some examples with and without "ALL" (the symbol b
          denotes a space):

               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

       E. When used in the definition of a screen data item:

            a. A figurative constant may not be supplied as
               <literal-1>.

            b. Any "FROM" (see FROM), "TO" (see TO) or "USING"
               (see USING) clause in the same data item's
               definition will be ignored.

            c. If there is no picture clause specified, the size of the
               screen data item will be the length of the <literal-1>
               value.

            d. If there is no picture clause and the "ALL" option is
               specified, the "ALL" option will be ignored.

       F. 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 GNU
          COBOL may find interesting.  So, here are the three standard
          approaches:

            a. 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).

            b. 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).

            c. 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!

       G. 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".  GNU COBOL, however, has
          neither of these restrictions!

          Observe the following example, which illustrates a fourth
          manner in which tables may be initialized in GNU COBOL:

               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 itsm'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 GNU COBOL 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 }

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

The "USING" clause defines the arguments that will be passed to a GNU
COBOL program which is serving as a subprogram.

  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" clause should only be used on the procedure division
     header of subprograms (subroutines or user-defined functions).

  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 GNU COBOL subprogram expects that all arguments to it will be
     one of two things:

        * The memory address of the actual data item (allocated in the
          calling program) that is being passed to the subprogram.

        * A numeric, full-word, binary value (i.e. "USAGE BINARY-LONG"
          (see USAGE)) which is the actual argument being passed to
          the subprogram.

     In the case of the former, the "USING" clause on the procedure
     division header should describe the argument via the "BY REFERENCE" clause
     -- in the latter case, a "BY VALUE" specification should be coded.
     This allows the code generated by the compiler to properly
     reference the subprogram arguments at run-time.

  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 GNU COBOL program, this can improve
     compatibility with a C-language calling program.

 12. The "OPTIONAL" keyword, legal only on "BY REFERENCE" arguments,
     allows calling programs to code "OMITTED" for that corresponding
     argument when they call this subprogram.  See CALL. for
     additional information on this feature.

6.2. PROCEDURE DIVISION CHAINING
================================

             PROCEDURE DIVISION Main-Program-Argument Syntax
=======================================================================

 [ BY REFERENCE ] [ OPTIONAL ] identifier-1
      ~~~~~~~~~     ~~~~~~~~

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

The "CHAINING" term provides one mechanism a programmer may use to
retrieve command-line arguments passed to a program at execution time.

  1. "PROCEDURE DIVISION CHAINING" may only be coded in a main program
     (that is, the first program executed when a compiled GNU COBOL
     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:

       A. When a GNU COBOL program is excecuted 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".

       B. 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.

       C. 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.

       D. If there are more tokens than there are arguments, the excess
          tokens will be discarded.

       E. 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.

       F. 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.

       G. 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.

       H. 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.  Un-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 characterset.

          This behavior 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
 ~~~~~~~~~

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

The RETURNING clause on the PROCEDURE DIVISION header documents that
the subprogram in which the clause appears will be returning a numeric
value back to the program that called it.

  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:

       A. 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.

       B. 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.

       C. 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 ona 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', and the names you create for
those sections and paragraphs are called 'Procedure Names'.

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 GNU COBOL
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:

        * "ALTER <procedure-name>"

        * "GO TO <procedure-name>"

        * "MERGE ... OUTPUT PROCEDURE <procedure-name>"

        * "PERFORM <procedure-name>"

        * "SORT ... INPUT PROCEDURE <procedure-name>" and/or "SORT ...
          INPUT PROCEDURE <procedure-name>"

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" and "AFTER EC" clauses are
syntactically recognized but are otherwise non-functional.

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

The "DECLARATIVES" area of the procedure division allows the programmer
to define a series of "trap" procedures (referred to as declarative
procedures) capable of intercepting certain events that may occur at
program execution time.  The syntax diagram above shows the format of a
single such procedure.

  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" clause:

       A. <identifier-2> must be a report group.

       B. 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" clause:

       A. 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").

       B. 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 nor
          "-debug" switch will activate this feature.

       C. Any "USE FOR DEBUGGING" declarative procedures will be
          ignored at execution time unless the "COB_SET_DEBUG" run-time
          environment variable (see Run Time Environment Variables)
          has been set to a value of "Y", "y" or "1".

       D. 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" clause defines a
     declarative procedure invoked any time a failure is encountered
     with the specified I/O type (or against the specified file(s)).

  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
=====================

COBOL uses parenthesis to specify the subscripts used to reference
table entries (tables in COBOL are what other programming languages
refer to as arrays).

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
================================

COBOL allows data names to be duplicated within a program, provided
references to those data names may be made in such a manner as to make
those references unique through a process known as qualification.

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 COBOL '85 standard introduced the concept of a reference modifier
to facilitate references to only a portion of a data item; GNU COBOL
fully supports reference modification.

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                          }

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

Arithmetic expressions are formed using four categories of operations
-- exponentiation, multiplication & division, addition & subtraction,
and sign specification.

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 GNU COBOL 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).

Expression             Result  Notes
---------------------------------------------------------------------------
3 * 4 + 1              13      * has precedence over +
4 * 2 ^ 3  - 10        22      2^3 is 8 (^ has precedence over *), times
                               4 is 32, minus 10 is 22.
(4 * 2) ^ 3  - 10      502     Parenthesis 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
                               exponention operator, so the
                               multiplication happens first); 8 ^ 3 is
                               512, minus 10 is 502.
5 / 2.5 + 7 * 2 -      15.35   Integer and non-integer operands may be
1.15                           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
=============================

Conditional expressions are expressions which identify the
circumstances under which a program may take an action or cease taking
an action.  As such, conditional expressions produce a value of TRUE or
FALSE.

There are seven types of conditional expressions, as discussed in the
following sections.

6.10.1. Condition Names
-----------------------

These are the simplest of all conditions.  Observe the following code:

     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     }

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

Class conditions evaluate the type of data that is currently stored in
a data item.

  1. The "NUMERIC" class test considers only the characters "0", "1",
     ... , "9" to be numeric; only a data item containing nothing but
     digits will pass a "NUMERIC" class test.  Spaces, decimal points,
     commas, currency signs, plus signs, minus signs and any other
     characters except the digit characters will all fail "NUMERIC"
     class tests.

  2. The "ALPHABETIC" class test considers only upper-case letters,
     lower-case letters and spaces to be alphabetic in nature.

  3. The "ALPHABETIC-LOWER" and "ALPHABETIC-UPPER" class conditions
     consider only spaces and the respective type of letters to be
     acceptable in order to pass such a class test.

  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.  GNU COBOL has no such
     restrictions.

  8. The "OMITTED" class condition is used when it is necessary for a
     subprogram to determine whether or not a particular argument was
     passed to it.  In such class conditions, <identifier-1> must be a
     linkage section item defined on the "USING" clause of the
     subprograms "PROCEDURE DIVISION" header.  See PROCEDURE DIVISION USING,
     for additional information.

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     }
                           ~~~~

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

Sign conditions evaluate the numeric state of a data item defined with
a "PICTURE" (see PICTURE) and/or "USAGE" (see USAGE) that
supports numeric values.

  1. A "POSITIVE" or "NEGATIVE" class condition will be TRUE only if
     the value of <identifier-1> is strictly greater than or less than
     zero, respectively.

  2. A "ZERO" class condition can be passed only if the value of
     <identifier-1> is exactly zero.

  3. The "NOT" option reverses the TRUE/FALSE value of the condition.

6.10.4. Switch-Status Conditions
--------------------------------

In the "SPECIAL-NAMES" (see SPECIAL-NAMES) paragraph, an external
switch name can be associated with one or more condition names.  These
condition names may then be used to test the ON/OFF status of the
external switch.

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    }
 { ~~~~      ~~ ~~~~~       }
 { =                        }
 { >                        }
 { >=                       }
 { <                        }
 { <=                       }

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

These conditions evaluate how two different values "relate" to each
other.

  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  }
                         { ~~  }

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

A combined condition is one that computes a TRUE/FALSE value from the
TRUE/FALSE values of two other conditions (which could themselves be
combined conditions).

  1. If either condition has a value of TRUE, the result of "OR"ing the
     two together will result in a value of TRUE.  "OR"ing two FALSE
     conditions will result in a value of FALSE.

  2. In order for "AND" to yield a value of TRUE, both conditions must
     have a value of TRUE.  In all other circumstances, "AND" produces
     a FALSE value.

  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
 ~~~

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

A condition may be negated by prefixing it with the "NOT" operator.

  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
====================

All COBOL implementations distinguish between sentences and statements
in the procedure division.  A 'Statement' is a single executable COBOL
instruction.  For example, these are all statements:

     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 GNU COBOL 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' is defined as any arbitrarily long sequence of
statements, followed by a period (.) character.  The period character
is what terminates the scope of a set of statements.  Therefore, our
example should have been coded 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

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
=====================================

Prior to the 1985 COBOL standard, using a period character was the only
way to signal the end of a statement's scope.

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" clause
-- being added to the COBOL language.

     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' (the first reserved word of a statement)
that needed such a thing was allowed to use an "END-verb" construct to
end it's scope without disrupting the scope of any other statement it
might have been in.  Any COBOL 85 compiler would have allowed the
following solution to our problem:

     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 (GNU COBOL 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 GNU COBOL, 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 GNU COBOL programs, however, I would strongly counsel you to use
the "END-verb" structures in those programs.

6.13. Concurrent Access to Files
================================

The manipulation of data files is one of the COBOL language's great
strengths.  There are features built into COBOL to deal with the
possibility that multiple programs may be attempting to access the same
file concurrently.  Multiple program concurrent access is dealt with in
two ways -- file sharing and record locking.

Not all GNU COBOL 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 GNU COBOL implementation was generated.

6.13.1. File Sharing
--------------------

GNU COBOL controls concurrent-file access at the highest level through
the concept of file sharing, enforced when a program attempts to open a
file.  This is accomplished via a UNIX operating-system routine called
"fcntl()".  That module is not currently supported by Windows and is
not present in the MinGW Unix-emulation package.  GNU COBOL builds
created using a MinGW environment will be incapable of supporting
file-sharing controls -- files will always be shared in such
environments.  A GNU COBOL build created using the Cygwin environment
on Windows would have access to "fcntl()" and therefore will support
file sharing.  Of course, actual Unix builds of GNU COBOL, as well as
OSX builds, should have no issues because "fcntl()" should be
available.

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" clause:

    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
----------------------

Record-locking is supported by advanced file-management software
built-in to the GNU COBOL implementation you are using.  This software
provides a single point-of-control for access to files -- usually
"ORGANIZATION INDEXED" (see ORGANIZATION INDEXED) files.  One such
runtime package capable of doing this is the Berkely Database (BDB)
package -- a package frequently used in GNU COBOL builds to support
indexed files.

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 GNU COBOL build you are using was configured to use the
     Berkely Database (BDB) package for indexed file I/O, record
     locking will be available by using the "DB_HOME" run-time
     environment variable (see Run Time Environment Variables).

  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" clause,
     every time a record is read from the file, that record is
     automatically locked.  Other programs may access other records
     within the file, but not a locked record.

  4. If the file's "SELECT" contains a "LOCK MODE IS MANUAL" clause,
     locks are placed on records only when a "READ" statement executed
     against the file includes a "LOCK" clause (this clause will be
     discussed shortly).

  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...

        * ...terminates, or ...

        * ...executes a "CLOSE" statement (see CLOSE) against the
          file, or ...

        * ...executes an "UNLOCK" statement (see UNLOCK) against
          the file, or ...

        * ...executes a "COMMIT" statement (see COMMIT) or ...

        * ...executes a "ROLLBACK" statement (see ROLLBACK).

  6. If the "LOCK ON" clause is not specified, then the next I/O
     statement your program executes, except for "START" (see
     START), will release the lock.  This is referred to as 'single
     record locking'.

  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 GNU COBOL 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 GNU COBOL 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 47 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
          47 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 ]
   ~~~    ~~~

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

"AT END" clauses may be specified on "READ" (see READ), "RETURN"
(see RETURN), "SEARCH" (see SEARCH) and "SEARCH ALL" (see
SEARCH ALL) statements.

  1. The following points pertain to the use of these clauses on "READ"
     (see READ) and "RETURN" (see RETURN) statements:

       A. 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.

       B. 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:

       A. 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.

       B. The "NOT AT END" clause is not allowed on either form of
          table search.

6.14.2. CORRESPONDING
---------------------

Three GNU COBOL statements -- "ADD" (see ADD CORRESPONDING), "MOVE"
(see MOVE CORRESPONDING) and "SUBTRACT" (see SUBTRACT CORRESPONDING)
support the use of a "CORRESPONDING" option:

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>...

       A. ...must exist at the same relative structural "depth" of
          definition within <group-item-1> and <group-item-2>,
          respectively

       B. ...and all "parent" data items defined within each group item
          must have identical (but non-"FILLER") names.

  3. When used with a "MOVE" verb...

       A. ...one of <data-item-1> or <data-item-2> (but not both) is
          allowed to be a group item

       B. ...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 matchup violates rule #4):

                              A, B, C, G

The following are the CORRESPONDING matchups that passed rule #1 (but
failed on another rule), and the reasons why they failed.

Data    Failure Reason
Item
--------------------------------------------------------------------------
"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 ]
   ~~~ ~~~~~~~

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

"INVALID KEY" clauses may be specified on "DELETE" (see DELETE),
"READ" (see Random READ), "REWRITE" (see REWRITE), "START"
(see START) and "WRITE" (see WRITE) statements.

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" clause will cause
<imperative-statement-2> to be executed if the statement's execution
was successful.

6.14.4. ON EXCEPTION + NOT ON EXCEPTION
---------------------------------------

                           ON EXCEPTION Syntax
=======================================================================

 [ ON EXCEPTION imperative-statement-1 ]
      ~~~~~~~~~
 [ NOT ON EXCEPTION imperative-statement-2 ]
   ~~~    ~~~~~~~~~

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

"EXCEPTION" clauses may be specified on "ACCEPT" (see ACCEPT),
"CALL" (see CALL) and "DISPLAY" (see DISPLAY) statements.

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 GNU COBOL 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" clause will cause
<imperative-statement-2> to be executed if the statement's execution
was successful.

6.14.5. ON OVERFLOW + NOT ON OVERFLOW
-------------------------------------

                           ON OVERFLOW Syntax
=======================================================================

 [ ON OVERFLOW imperative-statement-1 ]
      ~~~~~~~~
 [ NOT ON OVERFLOW imperative-statement-2 ]
   ~~~    ~~~~~~~~

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

"OVERFLOW" clauses may be specified on "CALL" (see CALL), "STRING"
(see STRING) and "UNSTRING" (see UNSTRING) statements.

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 GNU COBOL 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" clause will cause
<imperative-statement-2> to be executed if the statement's execution
was successful.

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 ]
   ~~~    ~~~~ ~~~~~

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

"SIZE ERROR" clauses may be included on "ADD" (see ADD), "COMPUTE"
(see COMPUTE), "DIVIDE" (see DIVIDE), "MULTIPLY" (see
MULTIPLY) and "SUBTRACT" (see SUBTRACT) statements.

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 GNU COBOL runtime library) to the SYSERR device (pipe 2) and
will also abort the program.

An optional "NOT ON SIZE ERROR" clause will cause
<imperative-statement-2> to be executed if the arithmetic statement's
execution was successful.

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             }
                     ~~~~~~~~~~

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

GNU COBOL provides for control over the final rounding process applied
to the receiving fields on all arithmetic verbs.  Each of the
arithmetic statements ("ADD" (see ADD), "COMPUTE" (see
COMPUTE), "DIVIDE" (see DIVIDE), "MULTIPLY" (see MULTIPLY)
and "SUBTRACT" (see SUBTRACT)) statements allow an optional
"ROUNDED" clause to be applied to each receiving data item.

The following rules apply to the rounding behavior 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 behavior 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
=======================

GNU COBOL, like other COBOL dialects, includes a number of data items
that are automatically available to a programmer without the need to
actually define them in the data division.  COBOL refers to such items
as registers or special registers.  The special registers available to
a GNU COBOL program are as follows:

"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
=========================

GNU COBOL supports a wide variety of "intrinsic functions" that may be
used anywhere in the PROCEDURE DIVISION where a literal is allowed.
For example:

     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 to the GNU COBOL compiler when you
compile your programs.

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 GNU COBOL 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)
 ~~~

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

This function determines and returns the absolute value of the <number>
(a numeric literal or data item) supplied as an argument.

6.16.2. ACOS
------------

                          ACOS Function Syntax
=======================================================================

 ACOS(cosine)
 ~~~~

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

The "ACOS" function determines and returns the trigonometric
arc-cosine, or inverse cosine, of the <cosine> value (a numeric literal
or data item) supplied as an argument.

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)
 ~~~~~~~

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

This function returns a numeric value approximating the ratio of an
annuity paid at the specified <interest-rate> (numeric data item or
literal) for each of the specified <number-of-periods> (numeric data
items or literals).

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 uf 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 "ASIN" function determines and returns the trigonometric arc-sine,
or inverse sine, of the <sine> value (a numeric literal or data item)
supplied as an argument.

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)
 ~~~~

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

Use this function to determine and return the trigonometric
arc-tangent, or inverse tangent, of the <tangent> value (a numeric
literal or data item) supplied as an argument.

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)
 ~~~~~~~~~~~

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

"BYTE-LENGTH" returns the length -- in bytes -- of the specified
<string> (a group item, "USAGE DISPLAY" elementary item or alphanumeric
literal).  This intrinsic function is identical to the "LENGTH-AN"
(see LENGTH-AN) function.  Note that the value returned by this
function is not necessarily the number of characters comprising
<string>, but rather the number of actual bytes required to store it.

For example, if <string> is encoded using a double-byte characterset
such as UNICODE (where each character is represented by 16 bits of
storage, not the 8-bits inherent to charactersets 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)
 ~~~~

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

This function returns the character in the ordinal position specified
by the <integer> argument (a numeric integer literal or data item with
a value of 1 or greater) from the "COLLATING SEQUENCE" (see
OBJECT-COMPUTER) being used by the program.

For example, if the program is using the (default) ASCII characterset,
CHAR(34) returns the 34th character in the ASCII characterset -- 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)
 ~~~~~~~~~~~~~~~~~

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

This function returns a 12-digit numeric result, the first seven digits
of which are the integer value of the <days> argument (a numeric data
item or literal) and the last five of which are the integer value of
the <seconds> argument (also a numeric data item or literal).

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 ]...)
 ~~~~~~~~~~~

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

This function concatenates the <string-1>, <string-2>, ... (group
items, "USAGE DISPLAY" elementary items and/or alphanumeric literals)
together into a single string result.

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 "COS" function determines and returns the trigonometric cosine of
the <angle> (a numeric literal or data item) supplied as an argument.

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
 ~~~~~~~~~~~~~~~

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

The "CURRENCY-SYMBOL" function returns the currency symbol character
currently in effect for the locale under which your program is running.
On UNIX systems, your locale is established via the "LANG" run-time
environment variable (see Run Time Environment Variables)
environment variable.  On Windows, the Control Panel's "Regional and
Language Options" define the locale.

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
 ~~~~~~~~~~~~

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

Returns the current date and time as the following 21-character
structure:

     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)
 ~~~~~~~~~~~~~~~

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

This function returns a numeric calendar date in yyyymmdd (i.e.
Gregorian) format.  The date is determined by adding the number of days
specified as <integer> (a numeric integer data item or literal) to the
date December 31, 1600.  For example, "DATE-OF-INTEGER(1)" returns
16010101 while "DATE-OF-INTEGER(150000)" returns 20110908.

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 ])
 ~~~~~~~~~~~~~~~~

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

You can use this function to convert the six-digit Gregorian date
specified as <yymmdd> (a numeric integer data item or literal) to an
eight-digit format (yyyymmdd).

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)
 ~~~~~~~~~~~~~~

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

This function returns a calendar date in yyyyddd (i.e. Julian) format.
The date is determined by adding the number of days specified as
integer (a numeric integer data item or literal) to December 31, 1600.
For example, "DAY-OF-INTEGER(1)" returns 1601001 while
"DAY-OF-INTEGER(250000)" returns 2011251.

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])
 ~~~~~~~~~~~~~~

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

You can use this function to convert the five-digit Julian date
specified as <yyddd> (a numeric integer data item or literal) to a
seven-digit numeric Julian format (yyyyddd).

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
 ~

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

This function returns the mathematical constant "E" (the base of
natural logarithms).  The maximum precision with which this value may
be returned is 2.7182818284590452353602874713526625.

Since this function has no arguments, no parenthesis should be
specified.

6.16.18. EXCEPTION-FILE
-----------------------

                     EXCEPTION-FILE Function Syntax
=======================================================================

 EXCEPTION-FILE
 ~~~~~~~~~~~~~~

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

This function returns I/O exception information from the most-recently
executed input or output statement.  The information is returned as a
34-character string, where the first two characters are the two-digit
file status value (see File Status Codes) and the remaining 32 are
the <file-name-1> specification from the file's "SELECT" (see
SELECT) statement.

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
 ~~~~~~~~~~~~~~~~~~

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

This function returns exception information from the most-recently
failing statement.  The information is returned to a 1023 character
string in one of the following formats, depending on the nature of the
failure:

   * primary-entry-point-name; paragraph OF section; statement-number

   * primary-entry-point-name; section; statement-number

   * primary-entry-point-name; paragraph; statement-number

   * primary-entry-point-name; statement-number

Since this function has no arguments, no parenthesis should be
specified.

The program must be compiled with the "-debug" switch, "-ftraceall"
switch or "-g" switch for this function to return any meaningful
information.

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
 ~~~~~~~~~~~~~~~~~~~

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

This function returns the most-recent COBOL statement that generated an
exception condition.

Since this function has no arguments, no parenthesis should be
specified.

The program must be compiled with the "-debug" switch, "-ftraceall"
switch or "-g" switch for this function to return any meaningful
information.

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
 ~~~~~~~~~~~~~~~~

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

This function returns the error type (a text string -- see column 2 of
the upcoming table for the possible values) from the most-recent COBOL
statement that generated an exception condition.

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.

Code  Error Type                Description
--------------------------------------------------------------------------
0101  EC-ARGUMENT-FUNCTION      Function argument error
0202  EC-BOUND-ODO              OCCURS ... DEPENDING ON data item out of
                                bounds
0204  EC-BOUND-PTR              Data-pointer contains an address that is
                                out of bounds
0205  EC-BOUND-REF-MOD          Reference modifier out of bounds
0207  EC-BOUND-SUBSCRIPT        Subscript out of bounds
0303  EC-DATA-INCOMPATIBLE      Incompatible data exception
0500  EC-I-O                    input-output exception
0501  EC-I-O-AT-END             I-O status "1x"
0502  EC-I-O-EOP                An end of page condition occurred
0504  EC-I-O-FILE-SHARING       I-O status "6x"
0505  EC-I-O-IMP                I-O status "9x"
0506  EC-I-O-INVALID-KEY        I-O status "2x"
0508  EC-I-O-LOGIC-ERROR        I-O status "4x"
0509  EC-I-O-PERMANENT-ERROR    I-O status "3x"
050A  EC-I-O-RECORD-OPERATION   I-O status "5x"
0601  EC-IMP-ACCEPT             Implementation-defined accept condition
0602  EC-IMP-DISPLAY            Implementation-defined display
                                condition
0A00  EC-OVERFLOW               Overflow condition
0A02  EC-OVERFLOW-STRING        STRING overflow condition
0A03  EC-OVERFLOW-UNSTRING      UNSTRING overflow condition
0B05  EC-PROGRAM-NOT-FOUND      Called program not found
0D03  EC-RANGE-INSPECT-SIZE     Size of replace item in inspect differs
1000  EC-SIZE                   Size error exception
1004  EC-SIZE-OVERFLOW          Arithmetic overflow in calculation
1005  EC-SIZE-TRUNCATION        Significant digits truncated in store
1007  EC-SIZE-ZERO-DIVIDE       Division by zero
1202  EC-STORAGE-NOT-ALLOC      The data-pointer specified in a FREE
                                statement does not identify currently
                                allocated storage
1203  EC-STORAGE-NOT-AVAIL      The amount of storage requested by an
                                ALLOCATE statement is not available

6.16.22. EXP
------------

                           EXP Function Syntax
=======================================================================

 EXP(number)
 ~~~

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

Computes and returns the value of the mathematical constant "e" raised
to the power specified by <number> (a numeric literal or data item).

6.16.23. EXP10
--------------

                          EXP10 Function Syntax
=======================================================================

 EXP10(number)
 ~~~~~

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

Computes and returns the value of 10 raised to the power specified by
<number> (a numeric literal or data item).

6.16.24. FACTORIAL
------------------

                        FACTORIAL Function Syntax
=======================================================================

 FACTORIAL(number)
 ~~~~~~~~~

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

This function computes and returns the factorial value of <number> (a
numeric literal or data item).

6.16.25. FRACTION-PART
----------------------

                      FRACTION-PART Function Syntax
=======================================================================

 FRACTION-PART(number)
 ~~~~~~~~~~~~~

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

This function returns that portion of <number> (a numeric data item or
a numeric literal) that occurs to the right of the decimal point.
"FRACTION-PART(3.1415)", for example, returns a value of 0.1415.  This
function is equivalent to the expression:

              <number> - FUNCTION INTEGER-PART(<number>)

6.16.26. HIGHEST-ALGEBRAIC
--------------------------

                    HIGHEST-ALGEBRAIC Function Syntax
=======================================================================

 HIGHEST-ALGEBRAIC(numeric-identifier)
 ~~~~~~~~~~~~~~~~~

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

This function returns the highest (i.e. largest or farthest away from 0
in a positive direction if <numeric-identifier> is signed) value that
could possibly be stored in the specified <numeric-identifier>.

6.16.27. INTEGER
----------------

                         INTEGER Function Syntax
=======================================================================

 INTEGER(number)
 ~~~~~~~

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

The "INTEGER" function returns the greatest integer value that is less
than or equal to <number> (a numeric literal or data item).

6.16.28. INTEGER-OF-DATE
------------------------

                     INTEGER-OF-DATE Function Syntax
=======================================================================

 INTEGER-OF-DATE(date)
 ~~~~~~~~~~~~~~~

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

This function converts <date> (a numeric integer data item or literal)
-- presumed to be a Gregorian calendar form standard date (YYYYMMDD) --
to internal date form (the number of days that have transpired since
1600/12/31).

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)
 ~~~~~~~~~~~~~~

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

This function converts <date> (a numeric integer data item or literal)
-- presumed to be a Julian calendar form standard date (YYYYDDD) -- to
internal date form (the number of days that have transpired since
1600/12/31).

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)
 ~~~~~~~~~~~~

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

Returns the integer portion of the value of <number> (a numeric literal
or data item).

6.16.31. LENGTH
---------------

                         LENGTH Function Syntax
=======================================================================

 LENGTH(string)
 ~~~~~~

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

Returns the length -- in characters -- of <string> (a group item,
"USAGE DISPLAY" elementary item or alphanumeric literal).

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 characterset such as UNICODE (where each character is
represented by 16 bits of storage, not the 8-bits inherent to
charactersets 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).

Comtrast 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 function returns the length -- in bytes of storage -- of <string>
(a group item, "USAGE DISPLAY" elementary item or alphanumeric
literal).

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 characterset such as UNICODE (where each
character is represented by 16 bits of storage, not the 8-bits inherent
to charactersets 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 ])
 ~~~~~~~~~~~~~~

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

The "LOCALE-COMPARE" function returns a character indicating the result
of comparing <argument-1> and <argument-2> using a culturally-preferred
ordering defined by a <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:

   * "<" -- If <argument-1> is determined to be less than <argument-2>

   * "=" -- If the two arguments are equal to each other

   * ">" -- If <argument-1> is determined to be greater than
     <argument-2>

See LOCALE Names, for a list of typically-available locale names.

6.16.34. LOCALE-DATE
--------------------

                       LOCALE-DATE Function Syntax
=======================================================================

 LOCALE-DATE(date [, locale ])
 ~~~~~~~~~~~

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

Converts the eight-digit Gregorian <date> (a numeric integer data item
or literal) from yyyymmdd format to the format appropriate to the
current locale.  On a Windows system, this will be the "short date"
format as set using Control Panel.

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 ])
 ~~~~~~~~~~~

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

Converts the four- (hhmm) or six-digit (hhmmss) <time> (a numeric
integer data item or literal) to a format appropriate to the current
locale.  On a Windows system, this will be the "time" format as set
using Control Panel.

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 ])
 ~~~~~~~~~~~~~~~~~~~~~~~~

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

Converts the number of <seconds> since midnight (a numeric integer data
item or literal) to a format appropriate to the current locale.  On a
Windows system, this will be the "time" format as set using Control
Panel.

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)
 ~~~

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

Computes and returns the natural logarithm (base "e") of <number> (a
numeric literal or data item).

6.16.38. LOG10
--------------

                          LOG10 Function Syntax
=======================================================================

 LOG10(number)
 ~~~~~

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

Computes and returns the base 10 logarithm of <number> (a numeric
literal or data item).

6.16.39. LOWER-CASE
-------------------

                       LOWER-CASE Function Syntax
=======================================================================

 LOWER-CASE(string)
 ~~~~~~~~~~

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

This function returns the value of <string> (a group item, "USAGE
DISPLAY" elementary item or alphanumeric literal), converted entirely
to lower case.

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)
 ~~~~~~~~~~~~~~~~

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

This function returns the lowest (i.e. smallest or farthest away from 0
in a negative direction if <numeric-identifier> is signed) value that
could possibly be stored in the specified <numeric-identifier>.

6.16.41. MAX
------------

                           MAX Function Syntax
=======================================================================

 MAX(number-1 [, number-2 ]...)
 ~~~

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

This function returns the maximum value from the specified list of
numbers (each <number-n> may be a numeric data item or a numeric
literal).

6.16.42. MEAN
-------------

                          MEAN Function Syntax
=======================================================================

 MEAN(number-1 [, number-2 ]...)
 ~~~~

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

This function returns the statistical mean value of the specified list
of numbers (each <number-n> may be a numeric data item or a numeric
literal).

6.16.43. MEDIAN
---------------

                         MEDIAN Function Syntax
=======================================================================

 MEDIAN(number-1 [, number-2 ]...)
 ~~~~~~

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

This function returns the statistical median value of the specified
list of numbers (each <number-n> may be a numeric data item or a
numeric literal).

6.16.44. MIDRANGE
-----------------

                        MIDRANGE Function Syntax
=======================================================================

 MIDRANGE(number-1 [, number-2 ]...)
 ~~~~~~~~

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

The "MIDRANGE" (middle range) function returns a numeric value that is
the arithmetic mean (average) of the values of the minimum and maximum
numbers from the supplied list.  Each <number-n> may be a numeric data
items or a numeric literal.

6.16.45. MIN
------------

                           MIN Function Syntax
=======================================================================

 MIN(number-1 [, number-2 ]...)
 ~~~

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

This function returns the minimum value from the specified list of
numbers (each <number-n> may be a numeric data item or a numeric
literal).

6.16.46. MOD
------------

                           MOD Function Syntax
=======================================================================

 MOD(value, modulus)
 ~~~

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

This function returns the value of <value> modulo <modulus>
(essentially the remainder from the division of <value> by <modulus>).
Both arguments may be numeric data items or numeric literals.  Either
(or both) may have a non-integer value.

6.16.47. MODULE-CALLER-ID
-------------------------

                    MODULE-CALLER-ID Function Syntax
=======================================================================

 MODULE-CALLER-ID
 ~~~~~~~~~~~~~~~~

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

This function returns the null string if it is executed within a main
program.  When executed with a subprogram, it returns the entry-point
name of the program that called the subprogram.

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
 ~~~~~~~~~~~

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

This function Returns the date the GNU COBOL program that is executing
the function was compiled, in the form yyyymmdd.

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
 ~~~~~~~~~~~~~~~~~~~~~

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

This function returns the fully-formatted date and time when the
program executing the function was compiled.  The exact format of this
returned string value may vary depending on the operating system and
GNU COBOL build type.

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
 ~~~~~~~~~

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

This function returmns the primary entry-point name (i.e. the
"PROGRAM-ID" or "FUNCTION-ID" of the program.  See IDENTIFICATION DIVISION,
for information on those clauses.

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
 ~~~~~~~~~~~

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

This function returns the full path to the executable version of this
GNU COBOL program.  The filename component of this value will be
exactly as typed on the command line, down to the use of upper- and
lowercase letters and presence (or absence) of any extension.

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 filename of the source code of the program (as specified on the
"cobc" command when the program was compiled) is returned by this
function.

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
 ~~~~~~~~~~~

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

This function returns the time the GNU COBOL program was compiled, in
the form hhmmss.

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
 ~~~~~~~~~~~~~~~~~~~~~~

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

"MONETARY-DECIMAL-POINT" returns the character used to separate the
integer portion from the fractional part of a monetary currency value
according to the rules currently in effect for the locale under which
your program is running.

On UNIX (including OSX, Windows/Cygwin and Windows/MinGW) systems, your
locale is established via the "LANG" run-time environment variable
(see Run Time Environment Variables) environment variable.  On
Windows, the Control Panel's Regional and Language Options define the
locale.

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
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

This function returns the character used to separate the thousands
digit groupings of monetary currency values according to the rules
currently in effect for the locale under which your program is
running.

On UNIX (including OSX, Windows/Cygwin and Windows/MinGW) systems, your
locale is established via the "LANG" run-time environment variable
(see Run Time Environment Variables) environment variable.  On
Windows, the Control Panel's Regional and Language Options define the
locale.

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
 ~~~~~~~~~~~~~~~~~~~~~

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

This function returns the character used to separate the integer
portion of a non-integer numeric item from the fractional part
according to the rules currently in effect for the locale under which
your program is running.

On UNIX (including OSX, Windows/Cygwin and Windows/MinGW) systems, your
locale is established via the "LANG" run-time environment variable
(see Run Time Environment Variables) environment variable.  On
Windows, the Control Panel's Regional and Language Options define the
locale.

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
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

This function returns the character used to separate the thousands
digit groupings of numeric values according to the rules currently in
effect for the locale under which your program is running.

On UNIX (including OSX, Windows/Cygwin and Windows/MinGW) systems, your
locale is established via the "LANG" run-time environment variable
(see Run Time Environment Variables) environment variable.  On
Windows, the Control Panel's Regional and Language Options define the
locale.

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 "NUMVAL" function converts a <string> (a group item, "USAGE
DISPLAY" elementary item or alphanumeric literal) to its corresponding
numeric value.

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])
 ~~~~~~~~

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

This function converts a <string> (a group item, "USAGE DISPLAY"
elementary item or alphanumeric literal) representing a currency value
to its corresponding numeric value.

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)
 ~~~~~~~~

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

This function converts a <string> (a group item, "USAGE DISPLAY"
elementary item or alphanumeric literal) representing a floating-point
value to its corresponding numeric value.

                    #   -#   +#   #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)
 ~~~

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

This function returns the ordinal position in the program characterset
(usually ASCII) corresponding to the 1st character of the <char>
argument (a group item, "USAGE DISPLAY" elementary item or alphanumeric
literal).

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 ]...)
 ~~~~~~~

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

This function returns the ordinal position in the argument list
corresponding to the <char-n> whose 1st character has the highest
position in the program collating sequence (usually ASCII).

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 ]...)
 ~~~~~~~

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

This function returns the ordinal position in the argument list
corresponding to the <char-n> whose 1st character has the lowest
position in the program collating sequence (usually ASCII).

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
 ~~

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

This function returns the mathematical constant "PI".  The maximum
precision with which this value may be returned is
3.1415926535897932384626433832795029.

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 ])
 ~~~~~~~~~~~~~

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

The "PRESENT-VALUE" function returns a value that approximates the
present value of a series of future period-end amounts specified by the
various <value-n> arguments at a discount rate specified by the <rate>
argument.

All arguments are numeric data items and/or numeric literals.

6.16.66. RANDOM
---------------

                         RANDOM Function Syntax
=======================================================================

 RANDOM[(seed)]
 ~~~~~~

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

This function returns a pseudo-random non-integer value in the range 0
to 1 (for example, 0.123456789).

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-ranom 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 uising 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 excecution 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 timeframes 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 ]...)
 ~~~~~

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

The "RANGE" function returns a value that is equal to the value of the
maximum <number-n> in the argument list minus the value of the minimum
<number-n> argument.

All <number-n> arguments are numeric data items and/or numeric
literals.

6.16.68. REM
------------

                           REM Function Syntax
=======================================================================

 REM(number,divisor)
 ~~~

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

This function returns a numeric value that is the remainder of <number>
divided by <divisor>.  Both arguments must be numeric data items or
numeric literals.

6.16.69. REVERSE
----------------

                         REVERSE Function Syntax
=======================================================================

 REVERSE(string)
 ~~~~~~~

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

This function returns the byte-by-byte reversed value of the specified
<string> (a group item, USAGE DISPLAY elementary item or alphanumeric
literal).

6.16.70. SECONDS-FROM-FORMATTED-TIME
------------------------------------

               SECONDS-FROM-FORMATTED-TIME Function Syntax
=======================================================================

 SECONDS-FROM-FORMATTED-TIME(format,time)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

This function decodes the string <time> -- whose value represents a
formatted time -- and returns the total number of seconds that string
represents.

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
 ~~~~~~~~~~~~~~~~~~~~~

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

This function returns the current time of day expressed as the total
number of elapsed seconds since midnight.

Since this function has no arguments, no parenthesis should be
specified.

6.16.72. SIGN
-------------

                          SIGN Function Syntax
=======================================================================

 SIGN(number)
 ~~~~

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

The "SIGN" function returns a -1 if the value of <number> (a numeric
literal or numeric data item) is negative, a zero if the value of
<number> is exactly zero and a 1 if the value of <number> if greater
than 0.

6.16.73. SIN
------------

                           SIN Function Syntax
=======================================================================

 SIN(angle)
 ~~~

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

This function determines and returns the trigonometric sine of the
specified <angle> (a numeric literal or numeric data item).

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 "SQRT" function returns a numeric value that approximates the
square root of <number> (a numeric data item or numeric literal with a
non-negative value).

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 ]...)
 ~~~~~~~~~~~~~~~~~~

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

This function returns the statistical standard deviation of the list of
<number-n> arguments (numeric data items or numeric literals).

6.16.76. STORED-CHAR-LENGTH
---------------------------

                   STORED-CHAR-LENGTH Function Syntax
=======================================================================

 STORED-CHAR-LENGTH(string)
 ~~~~~~~~~~~~~~~~~~

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

Returns the length -- in bytes -- of the specified "string" (a group
item, "USAGE DISPLAY" elementary item or alphanumeric literal), minus
the total number of trailing spaces, if any.

6.16.77. SUBSTITUTE
-------------------

                       SUBSTITUTE Function Syntax
=======================================================================

 SUBSTITUTE(string, from-1, to-1 [, from-n, to-n ]...)
 ~~~~~~~~~~

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

This function parses the specified <string>, replacing all occurrences
of the <from-n> strings with the corresponding <to-n> strings.

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 ]...)
 ~~~~~~~~~~~~~~~

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

The "SUBSTITUTE-CASE" function operates the same as the "SUBSTITUTE"
(see SUBSTITUTE) function, except that <from-n> string matching is
performed without regard to case.

All arguments are group items, "USAGE DISPLAY" elementary items or
alphanumeric literals.

6.16.79. SUM
------------

                           SUM Function Syntax
=======================================================================

 SUM(number-1 [, number-2 ]...)
 ~~~

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

The "SUM" function returns a value that is the sum of the <number-n>
arguments (these may be numeric data items or numeric literals).

6.16.80. TAN
------------

                           TAN Function Syntax
=======================================================================

 TAN(angle)
 ~~~

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

This function determines and returns the trigonometric tangent of the
specified <angle> (a numeric literal or numeric data item).

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)
 ~~~~~~~~~~~~~~~~~~

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

This function determines if the supplied <date> argument (a numeric
integer data item or literal) is a valid 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 signaling 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)
 ~~~~~~~~~~~~~~~~~

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

This function determines if the supplied <date> (a numeric integer data
item or literal) is a valid 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 signaling the problem lies with the year or day,
respectively.

6.16.83. TEST-NUMVAL
--------------------

                       TEST-NUMVAL Function Syntax
=======================================================================

 TEST-NUMVAL(string)
 ~~~~~~~~~~~

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

The "TEST-NUMVAL" function evaluates the specified <string> (a group
item, "USAGE DISPLAY" elementary item or alphanumeric literal) for
being appropriate for use as the <string> argument to a "NUMVAL" (see
NUMVAL) function, returning a TRUE value if it is appropriate and
FALSE otherwise.

6.16.84. TEST-NUMVAL-C
----------------------

                      TEST-NUMVAL-C Function Syntax
=======================================================================

 TEST-NUMVAL-C(string[,symbol])
 ~~~~~~~~~~~~~

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

This function evaluates the specified <string> (a group item, "USAGE
DISPLAY" elementary item or alphanumeric literal) for being appropriate
for use as the <string> argument to a "NUMVAL-C" (see NUMVAL-C)
function, returning a TRUE value if it is appropriate and FALSE
otherwise.

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)
 ~~~~~~~~~~~~~

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

This function evaluates the specified <string> (a group item, "USAGE
DISPLAY" elementary item or alphanumeric literal) for being appropriate
for use as the <string> argument to a "NUMVAL-F" (see NUMVAL-F)
function, returning a TRUE value if it is appropriate and FALSE
otherwise.

6.16.86. TRIM
-------------

                          TRIM Function Syntax
=======================================================================

 TRIM(string [, LEADING|TRAILING ])
 ~~~~           ~~~~~~~ ~~~~~~~~

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

This function removes "LEADING" or "TRAILING" spaces from the specified
<string> (a group item, "USAGE DISPLAY" elementary item or alphanumeric
literal).

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)
 ~~~~~~~~~~

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

This function returns the value of <string> (a group item, "USAGE
DISPLAY" elementary item or alphanumeric literal), converted entirely
to upper case.

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 ]...)
 ~~~~~~~~

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

This function returns the statistical variance of the specified list of
<number-n> arguments (these may be numeric data items or numeric
literals).

6.16.89. WHEN-COMPILED
----------------------

                      WHEN-COMPILED Function Syntax
=======================================================================

 WHEN-COMPILED
 ~~~~~~~~~~~~~

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

The "WHEN-COMPILED" intrinsic function, not to be confused with the
"WHEN-COMPILED" (see Special Registers) special register, returns
the date and time the program was compiled, in ASCII.

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 timezone 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 ])
 ~~~~~~~~~~~~

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

"YEAR-TO-YYYY" converts <yy> -- a two-digit year -- to a four-digit
format (yyyy).

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.1. ACCEPT
--------------

6.17.1.1. ACCEPT FROM CONSOLE
.............................

                       ACCEPT FROM CONSOLE Syntax
=======================================================================

   ACCEPT identifier-1
   ~~~~~~
    [ FROM mnemonic-name-1 ]
      ~~~~
 [ END-ACCEPT ]
   ~~~~~~~~~~

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

This format of the "ACCEPT" statement is used to read a value from the
console window or the standard input device and store it into a data
item (<identifier-1>).

  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
     honored.

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 ]    ~~~    ~~~~~~~~~
   ~~~~~~~~~~

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

This format of the "ACCEPT" statement is used to retrieve information
from the programs command-line.

  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" option, you will retrieve
     the entire set of arguments entered on the command line that
     executed the program, exactly as they were specified.  Parsing
     that returned data into its meaningful information will be your
     responsibility.

  3. By accepting from "ARGUMENT-NUMBER", you will be asking the GNU
     COBOL run-time system to parse the arguments from the command-line
     and return the number of arguments found.  Parsing will be
     conducted according to the following rules:

       A. 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.

       B. 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 imbedded within those
          quotation characters.

       C. 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", you will be asking the GNU
     COBOL run-time system to parse the arguments from the command-line
     and return the "current" argument.  You specify which argument
     number is "current" via the "ARGUMENT-NUMBER" option on the
     "DISPLAY" statement (see DISPLAY UPON COMMAND-LINE).  Parsing
     of arguments will be conducted according to the rules set forth
     above.

  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 ]
   ~~~~~~~~~~

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

This format of the "ACCEPT" statement is used to retrieve environment
variable values.

  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", you will be asking the GNU
     COBOL run-time system to retrieve the value of the environment
     variable whose name is currently in the "ENVIRONMENT-NAME" register.
     A value may be placed into the "ENVIRONMENT-NAME" register using
     the "ENVIRONMENT-NAME" option of the "DISPLAY" statement (see
     DISPLAY UPON ENVIRONMENT-NAME).

  3. A simpler approach to retrieving an environment variables value is
     to use the "ENVIRONMENT" option, where you specify the environment
     variable whose value is to be retrieved right on the "ACCEPT"
     statement itself.

  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-existant 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 [ FROM CRT ] [ MODE IS BLOCK ]
   ~~~~~~                ~~~~ ~~~     ~~~~    ~~~~~
          [ AT { | LINE NUMBER { integer-1    }            | } ]
            ~~ { | ~~~~        { identifier-2 }            | }
               { | COLUMN|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", "MODE IS BLOCK", "CONVERSION" and "UPDATE" clauses are
syntactically recognized but are otherwise non-functional.

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

This format of the "ACCEPT" statement is used to retrieve data from a
formatted console window screen.

  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" 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:

       A. 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.

       B. 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":

        * "AUTO" (see AUTO), "AUTO-SKIP" (see AUTO-SKIP),
          "AUTOTERMINATE" (see AUTOTERMINATE)

        * "BACKGROUND-COLOR" (see BACKGROUND-COLOR)

        * "BEEP" (see BEEP), "BELL" (see BELL)

        * "BLINK" (see BLINK)

        * "FOREGROUND-COLOR" (see FOREGROUND-COLOR)

        * "FULL" (see FULL), "LENGTH-CHECK" (see LENGTH-CHECK)

        * "HIGHLIGHT" (see HIGHLIGHT)

        * "LEFTLINE" (see LEFTLINE)

        * "LOWLIGHT" (see LOWLIGHT)

        * "OVERLINE" (see OVERLINE)

        * "PROMPT" (see PROMPT)

        * "REQUIRED" (see REQUIRED), "EMPTY-CHECK" (see
          EMPTY-CHECK)

        * "REVERSE-VIDEO" (see REVERSE-VIDEO)

        * "SECURE" (see SECURE), "NO-ECHO" (see NO-ECHO)

        * "UNDERLINE" (see UNDERLINE)

  8. The "SCROLL" option will cause the entire contents of the screen
     to be scrolled "UP" or "DOWN" by the specified number of lines
     before any value is displayed on the screen.  It is syntactically
     allowable to specify a "SCROLL UP" clause as well as a "SCROLL
     DOWN" clause.  In such an instance, it is the last one specified
     that will be honored.  If no "LINES" specification is made, "1
     LINE" will be assumed.

  9. The "TIMEOUT" option will cause the "ACCEPT" to wait no more than
     the specified number of seconds for input.  The wait count may be
     specified as a positive integer or a numeric data item with a
     positive value.

 10. This format of the "ACCEPT" statement will be terminated by any of
     the following events:

       A. When the 'Enter' key is pressed.

       B. Expiration of the "TIMEOUT" timer -- this will be treated as
          if the Enter key had been pressed with no data being
          entered.

       C. When a function key (Fn) is pressed.

       D. The pressing of the PgUp or PgDn keys, if the "COB_SCREEN_EXCEPTIONS"
          run-time environment variable (see Run Time Environment Variables)
          is set to any non-blank value.

       E. The pressing of the Esc key if both the "COB_SCREEN_ESC"
          run-time environment variable as well as "COB_SCREEN_EXCEPTIONS"
          run-time environment variable are set to any non-blank
          value.

       F. 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":

       A. 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.

       B. 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.

       C. 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":

       A. 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.

       B. 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.

       C. 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:

     Code       Meaning
     ---------------------------------------------------------------------
     0000       ENTER key pressed
     1001-1064  F1-F64, respectively, were pressed
     2001       PgUp was pressed
     2002       PgDn,was pressed
     2003       Up Arrow was pressed
     2004       Down-Arrow was pressed
     2006       PrtSc (Print Screen) was pressed
     2005       Esc was pressed
     8000       No data is available on screen ACCEPT
     9000       Fatal 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 GNU COBOL you're using.  For example, on a GNU
     COBOL 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 GNU COBOL 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 GNU COBOL, regardless of NumLock 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.

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              }
   ~~~~~~~~~~

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

This format of the "ACCEPT" statement is used to retrieve the current
system date, time or current day of the week and store it into a data
item.

  1. The data retrieved from the system and the format in which it is
     structured will vary, as follows:

     Syntax               Data Retrieved                     Format
     ----------------------------------------------------------------------
     "DATE"               Current date in Gregorian form     yymmdd
     "DATE YYYYMMDD"      Current date in Gregorian form     yyyymmdd
     "DAY"                Current date in Julian form        yyddd
     "DAY YYYYDDD"        Current date in Julian form        yyyyddd
     "TIME"               Time, including hundredths of a    hhmmssnn
                          second (nn)

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 ]
   ~~~~~~~~~~

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

This format of the "ACCEPT" statement is used to retrieve information
about the console window or about the user's interactions with it.

  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" and
     "COLUMNS" options:

       A. The "LINES" and "COLUMNS" options will retrieve the
          respective components of the size of the console display.

       B. 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.

       C. When the system is not running a windowing environment, the
          physical console screen attributes will be returned.

       D. Values of 0 will be returned if GNU COBOL was not generated
          to include screen I/O.

       E. 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" option may be used after the "ACCEPT FROM
     Screen-Info" statement (see ACCEPT FROM Screen-Info) has
     executed.  The result returned will be the four-digit "CRT STATUS"
     (see SPECIAL-NAMES) identifier value.  See CRT STATUS Codes,
     for the specific code values.

6.17.1.7. ACCEPT FROM Runtime-Info
..................................

                     ACCEPT FROM Runtime-Info Syntax
=======================================================================

   ACCEPT identifier-1
   ~~~~~~
          FROM { EXCEPTION STATUS }
          ~~~~ { ~~~~~~~~~ ~~~~~~ }
               { USER NAME        }
                 ~~~~ ~~~~
 [ END-ACCEPT ]
   ~~~~~~~~~~

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

This format of the "ACCEPT" statement is used to retrieve run-time
information such as the most-recent error exception code and the
current user's user name.

  1. The following points pertain to the use of the "EXCEPTION STATUS" option:

       A. <identifier-1> must be defined as a "PIC X(4)" item.

       B. See Error Exception Codes, for a complete list of the
          exception codes and their meanings.

       C. 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" option:

       A. 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).

       B. <identifier-1> should be defined large enough to receive the
          longest user-name on the system.

       C. If insufficient space is allocated, the returned value will
          be truncated.

       D. If excess space is allocated, the returned value will be
          padded with spaces (to the right).

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 ]
   ~~~~~~~

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

This format of the "ADD" statement generates an intermediate arithmetic
sum of the values of all <identifier-1> and <literal-1>) items. The
value of each <identifier-2> will be replaced, in turn, by the sum of
that <identifier-2>s value and the intermediate sum.

  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 ]
   ~~~~~~~

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

This format of the "ADD" statement generates the arithmetic sum of the
values of all <identifier-1>, <literal-1>) and <identifier-2> (if any)
items and then saves that sum to each <identifier-3>.

  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 ]
   ~~~~~~~

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

This format of the "ADD" statement generates code equivalent to
individual "ADD TO" (see ADD TO) statements for corresponding
matches of data items found subordinate to the two identifiers.

  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 ]           ~~~~~~~~~~~
       ~~~~~~~~~

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

The "ALLOCATE" statement is used to dynamically allocate memory at
run-time.

  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" clause will return the address of the
     allocated memory block into the specified "USAGE POINTER"
     <identifier-2> data item.  When this option is used, knowledge of
     the originally-requested size of the allocated memory block will
     be retained by the program in case a "FREE" (see FREE)
     statement is ever issued against <identifier-2>.

  7. When the <identifier-1> option is used in conjunction with
     "INITIALIZED" (or it's internationalized alternative
     "INITIALISED"), the allocated memory block will be initialized as
     if an "INITIALIZE <identifier-1> WITH FILLER ALL TO VALUE THEN TO
     DEFAULT" (see INITIALIZE) were executed.

  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
 ~~~~~                  ~~

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

The "ALTER" statement was used in the early years of the COBOL language
to edit the object code of a program *at execution time*, changing a
"GO TO" (see Simple GO TO) statement to branch to a spot in the
program different than where the "GO TO" statement was originally
compiled for.

  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 GNU COBOL for the
     purpose of enabling GNU COBOL 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 }

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

The "CALL" statement is used to transfer control to a subroutine.
See Sub-Programming, for the specifics of using subprograms with
GNU COBOL programs.

  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" / "STDCALL" option, if used,
     affects the linkage conventions that will be used to the
     subroutine being called, as follows:

       A. 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.

       B. The "STDCALL" option allows system-standard calling
          conventions (as opposed to GNU COBOL calling conventions) to
          be used when calling a subroutine.  The definition of what
          consititutes "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 GNU COBOL do not
          need this option.

       C. 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.

          Bit Supported Meaning if 0              Meaning if 1
          ------------------------------------------------------------------
          0   No        Arguments will be passed  Arguments will be passed
                        in right-to-left          in left-to-right
                        sequence                  sequence.

          1   No        The calling program will  The called program
                        flush processed           (subroutine) will flush
                        arguments from the        processed arguments from
                        argument stack.           the argument stack.

          2   Yes       The "RETURN-CODE"         The "RETURN-CODE"
                        special register (see special register will Special Registers)
                        not be updated (but any
                        will be updated in        "RETURNING" or "GIVING"
                        addition to any           data item still will).
                        "RETURNING" or "GIVING"
                        data item.

          3   Yes       If CALL "literal" is      If CALL "literal" is
                        used, the subroutine      used, the subroutine can
                        will be located and       only be located and
                        linked in with the        linked with the calling
                        calling program at        program at compilation
                        compile time or may be    time.
                        dynamically located and
                        loaded at execution
                        time, depending on
                        compiler switch settings
                        and operating system
                        capabilities.

          4   No        OS/2 "OPTLINK"            OS/2 "OPTLINK"
                        conventions will not be   conventions will be used
                        used to CALL the          to CALL the subprogram.
                        subprogram.

          5   No        Windows 16-bit            Windows 16-bit
                        "thunking" will not be    "thunking" will be used
                        in effect.                to call the subroutine
                                                  as a DLL.

          6   Yes       The STDCALL convention    The STDCALL convention,
                        will not be used.         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 GNU COBOL 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 "COB_PRE_LOAD" run-time
     environment variable (see Run Time Environment Variables).  If
     used, this will only pre-load those modules invoked via "CALL
     <literal-1>", as the runtime contents of <identifier-1> cannot be
     predicted.

  9. If the subprogram being called is a GNU COBOL 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 behavior will always apply to any
     subprogram's local-storage (if any), regardless of the use (or
     not) of "INITIAL".

 10. The "USING" clause defines a list of arguments that may be passed
     from the calling program to the subprogram.  The manner in which
     any given argument is passed to the subroutine depends upon the
     "BY" clause (if any) coded (or implied) for that argument, as
     follows:

       A. "BY REFERENCE" passes the address of the argument to the
          subprogram.  If the subprogram changes the contents of that
          argument, the change will be "visible" to the calling
          program.

       B. "BY CONTENT" passes the address of a copy of the argument to
          the subprogram.  If the subprogram changes the value of such
          an argument, the change only affects the copy back in the
          calling program, not the original version.

       C. "BY VALUE" passes the actual numeric value of the literal or
          identifiers contents as the argument.  This feature exists to
          provide compatibility with C, C++ and other languages and
          would not normally be used when calling GNU COBOL
          subprograms.  Only numeric literals or numeric data items
          should be passed in this manner.

       D. 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 GNU COBOL compiler was built with a specifically different
     argument limit specified for it.  If you have access to the GNU
     COBOL 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" clause allows you to specify a numeric data item
     into which the subroutine should return a numeric value.  If you
     use this clause on the "CALL", the subroutine should include a
     "RETURNING" (see PROCEDURE DIVISION RETURNING) clause on its
     procedure division header.  Of course, a subroutine may pass a
     value of any kind back in any argument passed "BY REFERENCE".

 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 }

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

The "CANCEL" statement unloads the dynamically-loadable subprogram
module containing the entry-point specified as <literal-1> or
<identifier-1> from memory.

  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 "COB_PHYSICAL_CANCEL" run-time
     environment variable (see Run Time Environment Variables).

6.17.7. CLOSE
-------------

                              CLOSE Syntax
=======================================================================

 CLOSE { file-name-1 [ { REEL|UNIT [ FOR REMOVAL ] } ] }...
 ~~~~~                 { ~~~~ ~~~~       ~~~~~~~   }
                       { WITH LOCK                 }
                       {      ~~~~                 }
                       { WITH NO REWIND            }
                              ~~ ~~~~~~

The "REEL", "LOCK" and "NO REWIND" clauses are syntactically recognized
but are otherwise non-functional, except for the "CLOSE...NO REWIND"
statement, which will generate a file status of 07 rather than the
usual 00 (but take no other action).

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

The "CLOSE" statement terminates the program's access to the specified
file(s).

  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
 ~~~~~~

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

The "COMMIT" statement performs an "UNLOCK" against every
currently-open file, but does not close any of the files.

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 ]
   ~~~~~~~~~~~

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

The "COMPUTE" statement provides a means of easily performing complex
arithmetic operations with a single statement, instead of using
cumbersome and possibly confusing sequences of "ADD", "SUBTRACT",
"MULTIPLY" and "DIVIDE" statements.  "COMPUTE" also allows the use of
exponentiation -- an arithmetic operation for which no other statement
exists in COBOL.

  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
 ~~~~~~~~

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

The "CONTINUE" statement is a no-operation statement that may be coded
anywhere an imperative statement (see Imperative Statement) may be
coded.

  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 "placeholder" -- 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 ]
   ~~~~~~~~~~

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

The "DELETE" statement logically deletes a record from a COBOL file.

  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
     descibed 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" in it's "SELECT" statement.

  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" in the file's "SELECT"
     statement.

  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 ]
   ~~~~~~~~~~~

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

This format of the "DISPLAY" statement displays the specified
identifier contents and/or literal values on the system output device
specified via the "UPON" clause.

  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" clause is specified, "UPON CONSOLE" will be assumed.
     If the "UPON" clause is specified, <mnemonic-name-1> must be one
     of the built-in output device names "CONSOLE", "PRINTER",
     "STDERR", "STDOUT", "SYSERR", "SYSLIST", "SYSLST" or "SYSOUT" or a
     mnemonic name assigned to one of those devices via the
     "SPECIAL-NAMES" (see SPECIAL-NAMES) paragraph.

     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 GNU COBOL.

     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 GNU COBOL.

  3. The "NO ADVANCING" clause, if used, will suppress the
     carriage-return / line-feed sequence that is normally added to the
     end of any console display.

  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 ]
   ~~~~~~~~~~~

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

This form of the "DISPLAY" statement may be used to specify the
command-line argument number to be retrieved by a subsequent "ACCEPT
FROM ARGUMENT-VALUE" statement (see ACCEPT FROM COMMAND-LINE) or to
specify a new value for the command-line arguments themselves.

  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", you
     will specify which argument (by its relative number) will be
     retrieved by a subsequent "ACCEPT FROM ARGUMENT-VALUE" statement.

  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 ]
   ~~~~~~~~~~~

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

This form of the "DISPLAY" statement can be used to create or modify
environment variables.

  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 GNU COBOL
     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 GNU COBOL
     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", "UPON CRT-UNDER" and "CONVERSION" clauses are
syntactically recognized but are otherwise non-functional.  They are
supported to provide compatibility with COBOL source written for other
COBOL implementations.

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

This format of the "DISPLAY" statement presents data onto a formatted
screen.

  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:

       A. 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.

       B. 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.

       C. 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":

             * "BACKGROUND-COLOR" (see BACKGROUND-COLOR)

             * "BEEP" (see BEEP), "BELL" (see BELL)

             * "BLANK" (see BLANK)

             * "BLINK" (see BLINK)

             * "ERASE" (see ERASE)

             * "FOREGROUND-COLOR" (see FOREGROUND-COLOR)

             * "HIGHLIGHT" (see HIGHLIGHT)

             * "LOWLIGHT" (see LOWLIGHT)

             * "OVERLINE" (see OVERLINE)

             * "REVERSE-VIDEO" (see REVERSE-VIDEO)

             * "UNDERLINE" (see UNDERLINE)

       D. 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 ]
   ~~~~~~~~~~

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

This format of the "DIVIDE" statement will divide a numeric value
(specified as a literal or numeric data item) into one or more numeric
data items, replacing the value in each of those data items with the
result(s).

  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 ]
   ~~~~~~~~~~

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

This format of the "DIVIDE" statement will divide one numeric value
(specified as a literal or numeric data item) into another numeric
value (also specified as a literal or numeric data item) and will then
replace the contents of one or more receiving data items with the
results of that division.

  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" clause is coded, there may be only one
     <identifier-3> specified.

  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 ]
   ~~~~~~~~~~

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

This format of the "DIVIDE" statement will divide one numeric value
(specified as a literal or numeric data item) into another numeric
value (also specified as a literal or numeric data item) and will then
replace the contents of one or more receiving data items with the
results of that division.

  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" clause is coded, there may be only one
     <identifier-3> specified.

  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     }
        ~~~~~

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

The "ENTRY" statement is used to define an alternate entry-point into a
subroutine, along with the arguments that subroutine will be
expecting.

  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" clause defines the arguments the subroutine
     entry-point supports.  This list of arguments must match up
     against the "USING" clause of any "CALL" statement that will be
     invoking the subroutine using this entry-point.

  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", "CONTENT" and "VALUE" are the same as
     the equivalent specifications on the "CALL" statement (see
     CALL).  Whatever specification will be used for an argument on
     the "CALL" to this entry-point should match the specification used
     in the corresponding <ENTRY-Argument>.  The same rules regarding
     the presence or absence of a "BY" clause on a "CALL" statement
     apply to the presence or absence of a "BY" clause on the
     corresponding argument of the "ENTRY" statement.

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    }   }

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

The "EVALUATE" statement provides a means of defining processing that
should take place under any number of mutually-exclusive conditions.

  1. The reserved words "THRU" and "THROUGH" are interchangeable.

  2. There must be at least one "WHEN" clause (in addition to any "WHEN
     OTHER" clause) specified on any "EVALUATE" statement.

  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" reserved
     word to separate each from the prior.

  4. Each "WHEN" clause (other than the "WHEN OTHER" clause, if any)
     must have the same number of <Selection-Object> clauses as there
     are <Selection-Subject> clauses.

  5. When using "THRU", the values on both sides of the "THRU" must be
     the same class (both numeric, both alphanumeric, etc.).

  6. A <partial-expression> is one of the following:

       A. A Class Condition without a leading <identifier-1> (see
          Class Conditions).

       B. A Sign Condition without a leading <identifier-1> (see Sign Conditions).

       C. 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:

       A. 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'.

       B. 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:

       A. 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.

       B. 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:

       A. The "WHEN OTHER" clause's <imperative-statement-other> will
          be executed, if such a clause was coded.

       B. 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:

       A. The <Selection-Object> is "ANY"

       B. The implied Relation Condition "<Selection-Subject> =
          <Selection Object>" is TRUE -- see Relation Conditions,
          for the rules on how the comparison will be made.

       C. The value of the <Selection-Subject> falls within the range
          of values specified by the "THRU" clause of the
          <Selection-Object>

       D. 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         }
          ~~~~~~~~~

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

The "EXIT" statement is a multi-purpose statement; it may provide a
common end point for a series of procedures, exit an inline PERFORM,
paragraph or section or it may mark the logical end of a subprogram,
returning control back to the calling program.

  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:

       A. 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.

       B. 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.

       C. 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:

       A. 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.

       B. 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").

       C. 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:

       A. The "EXIT PERFORM" and "EXIT PERFORM CYCLE" statements are
          intended to be used in conjunction with an inline "PERFORM"
          statement (see Inline PERFORM).

       B. An "EXIT PERFORM CYCLE" statement will terminate the current
          iteration of the inline "PERFORM", giving control to any
          "TIMES", "VARYING" and/or "UNTIL" clauses for them to
          determine if another cycle needs to be performed.

       C. An "EXIT PERFORM" statement will terminate the inline 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".

       D. This last example shows the final modification to the
          previous examples by using an inline "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:

       A. 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.

       B. 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.

       C. If executed by a main program, neither the "EXIT PROGRAM" nor
          "EXIT FUNCTION" statements will take any action.

       D. 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 }...
 ~~~~     ~~~~~~~

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

The "FREE" statement releases memory previously allocated to the
program by the "ALLOCATE" statement (see ALLOCATE).

  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  }

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

The "GENERATE" statement presents data to a report.

  1. The following points apply when <identifier-1> is specified:

       A. <identifier-1> must be the name of a "DETAIL" (see RWCS Lexicon)
          report group.

       B. If necessary, <identifier-1> may be qualified with a report
          name.

       C. 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.

       D. 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.

       E. If at least one "GENERATE" statement of this form is executed
          against a report, the report is said to be a 'detail report'.
          If no "GENERATE" statements of this form are executed
          against a report, the report is said to be a 'summary report'.

  2. The following points apply when <report-name-1> is specified:

       A. <report-name-1> must be the name of a report having an "RD"
          defined for it in the report section.

       B. There must be at least one "CONTROL" (see RWCS Lexicon)
          group defined for <report-name-1>.

       C. There cannot be more than one "DETAIL" group defined for
          <report-name-1>.

       D. 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.

       E. <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.

       F. 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'.  If at least one "GENERATE
          <identifier-1>" is executed, the report is considered to be a
          'detail 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
 ~~~~~~

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

The "GOBACK" statement is used to logically terminate an executing
program.

  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
 ~~

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

This form of the "GO TO" statement unconditionally transfers control in
a program to the first executable statement within the specified
<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...

       A. ...an inline "PERFORM" (see PERFORM), the "PERFORM" is
          terminated as control of execution transfers to
          <procedure-name-1>.

       B. ...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>.

       C. ...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 accumu7lated 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
      ~~~~~~~~~

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

This form of the "GO TO" statement will transfer control to any one of
a number of specified procedure names depending on the numeric value of
the identifier specified on the statement.

  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...

       A. ...an inline "PERFORM" (see PERFORM), the "PERFORM" is
          terminated as control of execution transfers to the procedure
          named on the statement.

       B. ...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.

       C. ...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 accumu7lated 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 thru 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 ]
   ~~~~~~

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

The "IF" statement is used to conditionally execute an imperative
statement (see Imperative Statement) or to select one of two
different imperative statements to execute based upon the TRUE/FALSE
value of a conditional expression.

  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" clause is present.  Once <imperative-statement-1>
     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.

  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" may be substituted for either
     imperative-statement, but not both.  If control reaches a "NEXT
     SENTENCE" clause due to the truth or falsehood of
     <conditional-expression>, control will be transferred to the first
     statement of the next sentence found in the program (the first
     statement after the next period).

     "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 GNU COBOL 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 ]
                ~~~~~~~

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

The "INITIALIZE" statement initializes each <identifier-1> with certain
specific values, depending upon the options specified.

  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 pictureless
          "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 initializable fields referred to
     as the field list in the remainder of this section, will include:

       A. Every <identifier-1> that is an elementary item, including
          any that may have the "REDEFINES" (see REDEFINES) clause
          in their descriptions.

       B. 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.

       C. If the optional "WITH FILLER" clause is included on the
          "INITIALIZE" statement, then every FILLER elementary item
          subordinate to each <identifier-1> will be included as well,
          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..

  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", "REPLACING" or "DEFAULT" clauses are coded, each
     member of the field list will be initialized as if the figurative
     constant "ZERO" (if the field list item is numeric or
     numeric-edited) or "SPACES" (otherwise) were being moved to it.

  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:

       A. If the "ALL" keyword was specified on the "VALUE" clause, all
          members of the field list with "VALUE" clauses will qualify.

       B. 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.

       C. 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 (gnucobsp.info), 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
 ~~~~~~~~

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

The "INITIATE" statement starts Report-Writer Control System (RWCS)
processing for a report.

  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:

        * All sum counters, if any, will be set to 0

        * The report's "LINE-COUNTER" special register (see Special Registers)
          will be set to 0

        * The report's "PAGE-COUNTER" special register will be set to
          1

  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 } |

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

The "INSPECT" statement is used to perform various counting and/or
data-alteration operations against strings.

  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" clause is specified, neither the "TALLYING" nor
     "REPLACING" clauses may be used.

  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:

       A. 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).

       B. The "REPLACING" clause replaces one or more substrings
          located in the inspect subject with a different, but
          equally-sized replacement substring.  If you need to replace
          a substring with another of a different length, consider
          using either the "SUBSTITUTE" intrinsic function (see
          SUBSTITUTE) or the "SUBSTITUTE-CASE" intrinsic function
          (see SUBSTITUTE-CASE).

       C. 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:

       A. If there is no "INITIAL" clause specified, the target range
          is the entire inspect subject.

       B. Either a "BEFORE" phrase, an "AFTER" phrase or both may be
          specified.  They may be specified in any order.

       C. The starting point of the target range will be the first
          character following the substring identified by the "AFTER"
          specification.  The ending point will be the last character
          immediately preceeding the substring identified by the
          "BEFORE" specification.

       D. If no "AFTER" is specified, the first character position of
          the target range will be character position #1 of the inspect
          subject.

       E. 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:

       A. 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.

       B. Each set of counting instructions contains the following
          information:

            a. 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.

            b. A Target Substring -- this is a sequence of characters
               to be located somewhere in the inspect subject and
               counted.  Target substrings may be defined as a literal
               value (figurative constants are allowed) or by the
               contents of an identifier.  If the target substring 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
               substrings could be identified from that replacement
               instruction, as follows:

               "ALL" -- identifies every possible target substring that
               occurs within the target range.  There are three
               occurrences of "ALL 'XX'" found in "aXXabbXXccXXdd".

               "LEADING" -- identifies only an occurrence of the target
               substring 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 substring 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.

       C. <identifier-2> will be incremented by 1 each time the target
          substring is found within the target range of the inspect
          subject.  The "INSPECT" statement will not zero-out
          <identifier-2> at the stary 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:

       A. 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-".

       B. Each set of replacement instructions contains the following
          information:

            a. 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.

            b. A Target Substring -- this is a sequence of characters
               to be located somewhere in the inspect subject and
               subsequently replaced with a new value.  Target
               substrings, 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 substring 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 substrings could be
               identified from that replacement instruction, as
               follows:

               "ALL" -- identifies every possible target substring that
               occurs within the target range.  There are three
               occurrences of "ALL 'XX'" found in "aXXabbXXccXXdd".

               "FIRST" -- the first occurrence of the target substring
               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 substring 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 substring
               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
               substring (see the next item) must be exactly one
               character in length.

            c. A Replacement Substring -- this is the sequence of
               characters that should replace the target substring.
               Replacement substrings 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
               substring.  Literals with "ALL" or figurative constants
               will be repeated as necessary to match the length of the
               target substring.  Identifiers specified as replacement
               substrings must be defined with a length equal to that
               of the target substring.

 13. When both "REPLACING" and "TALLYING" are specified:

       A. 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.

       B. 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.

       C. 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:

       A. 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).

       B. Unlike the "TALLYING" and "REPLACING" clauses, both of which
          may have multiple operations specified, there may be only one
          "CONVERTING" operation per "INSPECT".

       C. 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.

       D. 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.

       E. 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" clause is syntactically recognized but is otherwise
non-functional.

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

The "MERGE" statement merges the contents of two or more files that
have each been pre-sorted on a set of specified identical keys.

  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. GNU COBOL 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:

       A. None of them may be open at the time the "MERGE" is
          executed.

       B. Each of those files is assumed to be already sorted according
          to the specifications set forth on the "MERGE" statement's
          "KEY" clause.

       C. 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:

       A. As the "MERGE" statement begins execution, the first record
          in each of the "USING" files is read automatically.

       B. 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" clause.  The record that should be
          next in sequence will be written to the merge work file and
          the "USING" file from which that record came will be read so
          that its next record is available.  As end-of-file conditions
          are reached on "USING" files, those files will be excluded
          from further processing -- processing continues with the
          remaining files until all the contents of all of them have
          been exhausted.

       C. After the merge work file has been populated, the merged data
          will be written to each <file-name-3> if the "GIVING" clause
          was specified, or will be processed by utilizing an "OUTPUT
          PROCEDURE".

       D. When "GIVING" is specified, none of the <file-name-3> files
          can be open at the time the "MERGE" statement is executed.

       E. 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.

       F. 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 } ~~

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

The Simple "MOVE" statement moves a specific value to one or more
receiving data items.

  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...
 ~~~~ ~~~~                       ~~

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

The "MOVE CORRESPONDING" statement similarly-named items from one group
item to another.

  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 ]
   ~~~~~~~~~~

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

The "MULTIPLY BY" statement computes the product of one or more data
items (<identifier-2>) and either a numeric literal or another data
item.

  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 ]
   ~~~~~~~~~~

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

The "MULTIPLY GIVING" statement computes the product of two literals
and/or data items and saves that result in one or more other data
items.

  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", and "REVERSED" clauses are syntactically recognized
but are otherwise non-functional.

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

The "OPEN" statement makes one or more files described in your program
available for use.

  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 GNU COBOL 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 GNU COBOL runtime system
     will still terminate the program after your trap logic is
     executed.  Ultimately, you cannot recover from an open failure.

  6. The "INPUT", "OUTPUT", "I-O" and "EXTEND" open modes inform GNU
     COBOL of the manner in which you wish to use the file, as
     follows:

    "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" clause informs the GNU COBOL file runtime modules
     how you are willing to co-exist with any other GNU COBOL programs
     that may attempt to open the same file after your program does.
     See File Sharing, for an explanation of the "SHARING" clause.

  8. The "WITH LOCK" option will be functional only if your GNU COBOL
     build can support it.  GNU COBOL built for MinGW or native Windows
     will not, because the Unix "fcntl() primitive doesn't exist in
     those environments.  GNU COBOL built for Cygwin or Unix will.

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 } ~~~~~                                      }

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

This format of the "PERFORM" statement is used to transfer control to
one or more procedures, which will return control back when complete.
Execution of the procedure(s) can be done a single time, multiple
times, repeatedly until a condition becomes TRUE or forever (with some
way of breaking out of the control of the "PERFORM" or of halting
program execution within the procedure(s)).

  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' is defined as being the statements within
     <procedure-name-1>, the statements within <procedure-name-2> and
     all statements in all procedures defined between them.

  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", "UNTIL EXIT", "TIMES", <VARYING-Clause>
     (see VARYING) or "FOREVER" clauses, the code within the
     perform scope will be executed once, after which control will
     return to the statement following the "PERFORM".

  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" clause will control whether "UNTIL"
     testing occurs "BEFORE" the statements within the perform scope
     are executed on each iteration (creating the possibility -- if
     <conditional-expression-1> is initially TRUE -- that the
     statements within the perform scope will never be executed) or
     "AFTER" (guaranteeing the statements within the perform scope will
     be executed at least once).

     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 ]
   ~~~~~~~~~~~

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

This format of the "PERFORM" statement is identical in operation to the
procedural "PERFORM", except for the fact that the statement(s)
comprising the perform scope (<imperative-statement-1>) (see
Imperative Statement) are now specified in-line with the "PERFORM"
code rather than in procedures located elsewhere within the program.

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 ] ]...
           ~~~~~

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

The "VARYING" clause, available on both formats of the "PERFORM"
statement, is a looping mechanism that allows for the specification of
one or more numeric data items that will be initialized to a
programmer-specified value and automatically incremented by another
programmer-specified value after each loop iteration.

  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:

       A. When the "PERFORM" begins execution, the "FROM" value will be
          moved to <identifier>.

       B. 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).

       C. 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.

       D. 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.

       E. 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.

       F. 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 descibed above in steps (A) thru (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 ]
   ~~~~~~~~

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

This form of the "READ" statement retrieves the next (or previous)
record from a file.

  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" and "PREVIOUS" specify what direction of
     "travel" the reading process will take through the file.  If
     neither is specified, "NEXT" is assumed.

  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 GNU
     COBOL 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" clause
     is present, a copy of the just-retrieved record will be
     automatically moved to <identifier-1>.

 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 behaviors.

 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 ]
   ~~~~~~~~

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

This form of the "READ" statement retrieves an arbitrary record from an
"ORGANIZATION RELATIVE" (see ORGANIZATION RELATIVE) or
"ORGANIZATION INDEXED" (see ORGANIZATION INDEXED) file.

  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 GNU
     COBOL 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" clause tells the compiler how a record is to be
     located in the file.  If the clause is absent, and...

       A. ...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...

       B. ...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...

       A. ...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).

       B. ...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" clause is present,
     a copy of the just-retrieved record will be automatically moved to
     <identifier-1>.

 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 behaviors.

 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
 ~~~~~ ~~~~~

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

The "READY TRACE" statement turns procedure or procedure-and-statement
tracing on.

  1. In order for this statement to be functional, tracing code must
     have been generated into the compiled program using either the
     "-ftrace" switch (procedures only) or "-ftraceall" switch
     (procedures and statements).

  2. Tracing may be turned off at any point by executing the "RESET
     TRACE" statement (see RESET TRACE).

  3. The "COB_SET_TRACE" run-time environment variable (see Run Time Environment Variables)
     provides another way to control tracing.

6.17.32. RELEASE
----------------

                             RELEASE Syntax
=======================================================================

 RELEASE record-name-1 [ FROM { literal-1    } ]
 ~~~~~~~                 ~~~~ { identifier-1 }

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

The "RELEASE" statement adds a new record to a sort work file.

  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" clause will cause <literal-1> or
     <identifier-1> to be automatically moved into <record-name-1>
     prior to writing <record-name-1>'s contents to the <file-name-1>.
     If this clause is not specified, it is the programmer's
     responsibility to populate <record-name-1> with the desired data
     prior to executing the "RELEASE".

6.17.33. RESET TRACE
--------------------

                           RESET TRACE Syntax
=======================================================================

 RESET TRACE
 ~~~~~ ~~~~~

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

The "RESET TRACE" statement turns procedure or procedure-and-statement
tracing off.

  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 (procedures only) or "-ftraceall" switch (procedures
     and statements).

  3. The "COB_SET_TRACE" run-time environment variable (see Run Time Environment Variables)
     provides another way to control tracing.

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 ]
   ~~~~~~~~~~

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

The "RETURN" statement reads a record from a sort- or merge work file.

  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" clause is present, a copy of
     the just-retrieved record will be automatically moved to
     <identifier-1>.

  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 ]
   ~~~~~~~~~~~

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

The "REWRITE" statement replaces a logical record on a disk file.

  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" clause will cause <literal-1> or
     <identifier-1> to be automatically moved into <record-name-1>
     prior to writing <record-name-1>'s contents to the <file-name-1>.
     If this clause is not specified, it is the programmer's
     responsibility to populate <record-name-1> with the desired data
     prior to executing the "REWRITE".

  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):

       A. The record to be rewritten will be the one retrieved by the
          most-recently executed "READ" (see READ) of the file.

       B. 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):

       A. 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.

       B. 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 behaviors.

  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
 ~~~~~~~~

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

The "ROLLBACK" statement has the same effect as if an "UNLOCK"
statement (see UNLOCK) were executed against every open file in the
program.

  1. All locks currently being held for all open files will be
     released.

  2. See Record Locking, to review the various record locking
     behaviors.

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 ]
   ~~~~~~~~~~

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

The "SEARCH" statement is used to sequentially search a table, stopping
either once a specific value is located within the table or when the
table has been completely searched.

  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' --
     a data item with a "USAGE" (see USAGE) of "INDEX".  The search
     index is either the <index-name-1> identifier specified on the
     "VARYING" clause or -- if no "VARYING" is specified -- the "USAGE
     INDEX" data item implicitly created by an "INDEXED BY" (see
     OCCURS) clause in the table's definition.

  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:

       A. Each <conditional-expression-n> will be evaluated, in turn,
          until either one evaluates to a value of TRUE or all have
          evaluated to FALSE.

       B. 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".

       C. 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" clause, if any, will be executed.
               After that, control will fall into the first executable
               statement following the "SEARCH".

             * 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 ]
   ~~~~~~~~~~

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

The "SEARCH ALL" statement performs a binary, or half-interval, search
against a sorted table.  This is generally significantly faster than
performing a sequential "SEARCH" of a table, especially if the table
contains a large number of entries.

  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":

       A. The "OCCURS" clause of <table-name-1> must contain the
          following elements:

             * An "INDEXED BY" entry to define an implicit search index
               data item with a "USAGE" (see USAGE) of "INDEX".

             * An "ASCENDING KEY" or "DESCENDING KEY" clause to specify
               the field within the table by which all entries in the
               table are sorted.

       B. 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.

       C. 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" clause is to compare
     the key field(s) of the table, as indexed by the search index data
     item, against whatever literal and/or identifier values you are
     comparing the key field(s) to in the <conditional-expression-1> in
     order to locate the desired entry in the table.  The search index
     will be automatically varied in a manner designed to require the
     minimum number of tests.

  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:

       A. 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>.

       B. 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 thru 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).

       C. 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.

       D. 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 thru 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 }

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

The "SET ENVIRONMENT" statement provides a straight-forward means of
setting environment values from within a program.

  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 GNU COBOL
     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 GNU COBOL 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 }

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

The "SET <Program-Pointer>" statement allows you to retrieve the
address of a procedure division code module -- specifically the
"PROGRAM-ID", "FUNCTION-ID" or an entry-point established via the
"ENTRY" statement (see ENTRY).

  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 GNU COBOL; 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   }

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

The "SET ADDRESS" statement can be used to work with the addresses of
data items rather than their contents.

  1. When the "ADDRESS OF" clause is used before the "TO" you will be
     using this statement to alter the address of a linkage section or
     "BASED" (see BASED) data item.  Without that clause you will
     be assigning an address to one or more data items whose "USAGE"
     (see USAGE) is "POINTER".

  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 }

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

This statement assigns a value to a "USAGE INDEX" data item.

  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 }
                    ~~~~

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

Use this statement to increment or decrement the value of an index or
pointer by a specified amount.

  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 }
                              ~~~~~

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

The "SET <Condition Name>" statement provides one method of specifying
the TRUE / FALSE value of a level-88 condition name.

  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 }
                             ~~~

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

This form of the "SET" statement is used to turn switches on or 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     }
                                ~~~~~~~~~

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

The "SET ATTRIBUTE" statement may be used to modify one or more
attributes of a screen section data item at run-time.

  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" clause is syntactically recognized but is otherwise
non-functional.

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

This format of the "SORT" statement is designed to sort large volumes
of data according to one or more key fields.

  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. GNU COBOL 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:

       A. 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.

       B. When "USING" is specified, none of the <file-name-1> files
          may be open at the time the "SORT" statement is executed.

       C. When an input procedure is used, the procedure(s) specified
          on the "INPUT PROCEDURE" clause will be invoked as if by a
          procedural "PERFORM" statement (see Procedural PERFORM)
          with no "VARYING", "TIMES" or "UNTIL" options specified.
          Records will be loaded into the sort work file -- one at a
          time -- within the input procedure using the "RELEASE"
          statement (see RELEASE).  This, by the way, is how you
          could sort the contents of relative or indexed files.

          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.

       D. Once the input procedure terminates, the input phase is
          complete.

       E. 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 "COB_SORT_MEMORY" run-time environment
          variable (see Run Time Environment Variables) that you
          may use to allocate more or less memory to the sorting
          process.

 10. The following points pertain to the Sort Stage:

       A. 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.

       B. 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.

       C. 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 "TMPDIR" run-time environment
          variable, "TMP" run-time environment variable or "TEMP"
          run-time environment variable run-time environment variables
          (see Run Time Environment Variables) (checked for
          existence in that sequence).  These disk files will be
          automatically purged upon "SORT" termination or program
          execution termination (normal or otherwise).

 11. The following points pertain to the Output Stage:

       A. Once the sort stage is complete, a copy of the sorted data
          will be written to each <file-name-2> if the "GIVING" clause
          was specified.  None of the <file-name-2> files can be open
          at the time the sort is executed.

       B. When an output procedure is used, the procedure(s) specified
          on the "OUTPUT PROCEDURE" clause will be invoked as if by a
          procedural "PERFORM" statement (see Procedural PERFORM)
          with no "VARYING", "TIMES" or "UNTIL" options specified.
          Records will be retrieved from the sort work file -- one at a
          time -- within the output procedure using the "RETURN"
          statement (see RETURN).

          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.

       C. 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" clause is syntactically recognized but is otherwise
non-functional.

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

This format of the "SORT" statement sorts relatively small quantities
of data -- namely data contained in a data division table -- according
to one or more key fields.

  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. GNU COBOL 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 GNU COBOL 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 ]
   ~~~~~~~~~

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

The "START" statement defines the logical starting point within a
relative or indexed file for subsequent sequential read operations.  It
positions an internal logical record pointer to a particular record in
the file, but does not actually transfer any of that record's data into
the record buffer.

  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:

       A. If "FIRST" was specified, the logical record pointer will
          point to the first record in the file.

       B. If "LAST" was specified, the logical record pointer will
          point to the last record in the file.

       C. 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).

       D. 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                                               }

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

The "STOP" statement suspends program execution.  Some options will
allow program execution to resume while others return control to the
operating system.

  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" and "GIVING" are interchangeable.

  3. The "RUN" clause halts the program without displaying any special
     message to that effect.

  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" clause provides another means of returning a return
     code.  Using the "STATUS" clause is functionally equivalent to
     using the "RETURNING" clause.

  7. Using the "STATUS" clause without a <literal-2> or <identifier-2>
     will return a return code of 0 if the "NORMAL" keyword is used or
     a 1 if "ERROR" was specified.

  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 GNU COBOL 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 ]
   ~~~~~~~~~~

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

The "STRING" statement is used to concatenate all or a part of one or
more strings together, forming a new 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" data item -- <identifier-4> -- must be a non-edited
     elementary integer numeric data item with a value greater than
     zero.

  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'.  The initial value of the current character
     pointer will be the value of <identifier-4> at the time the
     "STRING" 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.

  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" clause specifies how much of each source item
     will be copied into <identifier-3>.  "DELIMITED BY SIZE" (the
     default if no "DELIMITED BY" clause is specified) causes the
     entire contents of the source item to be copied into
     <identifier-3>.

  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:

       A. The initial value of the current character pointer is less
          than 1 or greater than the number of characters in
          <identifier-3>, or...

       B. 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...

       C. 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 ]
   ~~~~~~~~~~~~

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

This format of the "SUBTRACT" statement generates the arithmetic sum of
all arguments that appear before the "FROM" (<identifier-1> or
<literal-1>) and subtracts that sum from each <identifier-2>.

  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 ]
   ~~~~~~~~~~~~

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

The "SUBTRACT GIVING" statement generates the arithmetic sum of all
arguments that appear before the "FROM" (<identifier-1> or
<literal-1>), subtracts that sum from the contents of <identifier-2>
and then replaces the contents of the identifiers listed after the
"GIVING" (<identifier-3>) with that result.

  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 ]
   ~~~~~~~~~~~~

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

The "SUBTRACT CORRESPONDING" statement generates code equivalent to
individual "SUBTRACT FROM" statements for corresponding matches of data
items found subordinate to the two identifiers.

  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
 ~~~~~~~~

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

The "SUPPRESS" statement causes the presentation of a report group to
be suppressed.

  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:

       A. Actual presentation of the report group in question.

       B. Processing of any "LINE" (see LINE) clauses within the
          report group in question.

       C. Processing of the "NEXT GROUP" (see NEXT GROUP) clause
          (if any) within the report group in question.

       D. Any modification to the "LINE-COUNTER" special register (see
          Special Registers).

       E. Any modification to the "PAGE-COUNTER" special register.

6.17.46. TERMINATE
------------------

                            TERMINATE Syntax
=======================================================================

 TERMINATE report-name-1...
 ~~~~~~~~~

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

The "TERMINATE" statement causes the processing of the specified
report(s) to be completed.

  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 }

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

The "TRANSFORM" statement scans a data item performing a series of
monoalphabetic substitutions, defined by the arguments before and after
the "TO" clause.

  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 GNU COBOL 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
 ~~~~~~

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

This statement synchronizes any as-yet unwritten file I/O buffers to
the specified file (if any) and releases any record locks held for
records belonging to <file-name-1>.

  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 GNU COBOL 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 GNU COBOL was generated.
     When a program using one of those GNU COBOL 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 ]
   ~~~~~~~~~~~~

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

The "UNSTRING" statement parses a string, extracting any number of
substrings from it.

  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 substrings starting from the
     current character pointer position.  Substrings are identified by
     using the various delimiter strings specified on the "DELIMITED BY" clause
     as inter-substring separators.

  9. Using the "ALL" option allows a delimiter sequence to be an
     arbitrarily long sequence of occurrences of the delimiter literal
     whereas its absence treats each occurrence as a separate
     delimiter.  When multiple delimiters are specified, they will be
     looked for in the source string in the sequence in which they are
     coded.

 10. Two consecutive delimiter sequences will identify a null
     substring.

 11. Identified substrings will be moved into each destination field in
     the sequence they are identified; values moved into a destination
     field will be truncated if the substring length exceeds the
     destination field length, or padded with spaces if the destination
     field length exceeds the substring 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" clause.
     If a "DELIMITER" clause is specified, <identifier-5> will have the
     delimiter character string used to identify the substring for the
     destination field moved into it.  If a destination field was not
     altered (because an insufficient number of substrings were
     identified), <identifier-5> for that destination field will also
     be unchanged.

 13. Each destination field may have an optional "COUNT" clause.  If a
     "COUNT" clause is specified, <identifier-6> will have the size of
     the substring (in characters) for the destination field moved into
     it.  If a destination field was not altered (because an
     insufficient number of substrings were identified), <identifier-6>
     for that destination field will also be unchanged.

 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:

       A. The initial value of the current character pointer is less
          than 1 or greater than the number of character positions in
          <identifier-1>, or...

       B. 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 ]
   ~~~~~~~~~

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

The "WRITE" statement writes a new record to an open file.

  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" clause will cause <literal-1> or
     <identifier-1> to be automatically moved into <record-name-1>
     prior to writing <record-name-1>'s contents to the appropriate
     file.  If this clause is not specified, it is the programmer's
     responsibility to populate <record-name-1> with the desired data
     prior to executing the "WRITE".

  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 behaviors.

  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:

        * A line-terminator sequence consisting of an ASCII
          carriage-return/line-feed character sequence (X'0D0A') if you
          are running a MinGW or native Windows build of GNU COBOL

        * A line-terminator sequence consisting of an ASCII line-feed
          character (X'0A') if you are running a Cygwin, Linix, Unix or
          OSX build of GNU COBOL

  8. The following points pertain to the use (or not) of the
     "ADVANCING" clause:

       A. 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)).

       B. 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.

       C. When "BEFORE ADVANCING" is used (or implied), the record is
          written to the file before the "ADVANCING" action writes
          line-terminator characters to the file.

       D. If "AFTER ADVANCING" is used (or implied), the "ADVANCING"
          action writes line-terminator characters to the file and then
          the record data is written to the file.

       E. 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").

       F. If the "LINAGE" (see File/Sort-Description) clause is
          absent from the file's "FD":

            a. The "ADVANCING PAGE" clause will introduce an ASCII
               formfeed character into the file either before the
               written record ("AFTER PAGE") or after the written
               record ("BEFORE PAGE").

            b. 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.

       G. If the LINAGE clause is present in the file's "FD":

            a. 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.

            b. 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 GNU COBOL
               run-time library, which provides tools such as the
               "LINAGE-COUNTER" special register (see Special Registers)
               and the "END-OF-PAGE" clause to deal with
               page formatting issues.

            c. 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
=================

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 preceed
     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 preceeded 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:

        * The date the report was generated

        * The current page number of the report

Page Heading

     A report group that appears at the top of every page of an
     RWCS-generated report. Information typically found sithin such a
     report group might be:

        * A title for the report

        * The date the report was generated

        * The current page number of the report

        * Column headings describing the fields within the detail
          group(s)

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:

   * REPORT HEADING

   * PAGE HEADING [1]

   * CONTROL HEADING(S) [2]

   * DETAIL GROUP(S) [2]

   * CONTROL FOOTING(S) [2]

   * "FINAL" CONTROL FOOTING

   * PAGE FOOTING [1]

   * REPORT FOOTING

[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 Unuseable 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 Unuseable 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 GNU COBOL 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 GNU COBOL 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 questiuons
     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' points of the report.

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' wwebsite 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 filenames 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 filenames.

The GNU COBOL 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 GNU COBOL 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 GNU COBOL Compiler
------------------------------------

The GNU COBOL 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".

Usage: cobc [options] file ...

Options:
  -help                 Display this message
  -version, -V          Display compiler version
  -info, -i             Display compiler build information
  -v                    Display the commands invoked by the compiler
  -x                    Build an executable program
  -m                    Build a dynamically loadable module (default)
  -std=<dialect>        Warnings/features for a specific dialect :
                          cobol2002   Cobol 2002
                          cobol85     Cobol 85
                          ibm         IBM Compatible
                          mvs         MVS Compatible
                          bs2000      BS2000 Compatible
                          mf          Micro Focus Compatible
                          default     When not specified
                        See config/default.conf and config/*.conf
  -free                 Use free source format
  -fixed                Use fixed source format (default)
  -O, -O2, -Os          Enable optimization
  -g                    Enable C compiler debug / stack check / trace
  -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
  -P(=<dir or file>)    Generate preprocessed program listing (.lst)
  -Xref                 Generate cross reference through 'cobxref'
                        (V. Coen's 'cobxref' must be in path)
  -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> to the COBOL compiler
  -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 default file extension

  -W                    Enable ALL warnings
  -Wall                 Enable all warnings except as noted below
  -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
  -Wparentheses         Warn lack of parentheses around AND within OR
  -Wstrict-typing       Warn type mismatch strictly
  -Wimplicit-define     Warn implicitly defined data items
  -Wcorresponding       Warn CORRESPONDING with no matching items
  -Wexternal-value      Warn EXTERNAL item with VALUE clause
  -Wcall-params         Warn non 01/77 items for CALL params
                        - NOT set with -Wall
  -Wcolumn-overflow     Warn text after column 72, FIXED format
                        - NOT set with -Wall
  -Wterminator          Warn lack of scope terminator END-XXX
                        - NOT set with -Wall
  -Wtruncate            Warn possible field truncation
                        - NOT set with -Wall
  -Wlinkage             Warn dangling LINKAGE items
                        - NOT set with -Wall
  -Wunreachable         Warn unreachable statements
                        - NOT set with -Wall

  -fsign=<value>        Define display sign representation
                        - ASCII or EBCDIC (Default : machine native)
  -ffold-copy=<value>   Fold COPY subject to value
                        - UPPER or LOWER (Default : no transformation)
  -ffold-call=<value>   Fold PROGRAM-ID, CALL, CANCEL subject to value
                        - UPPER or LOWER (Default : no transformation)
  -fdefaultbyte=<value> Initialize fields without VALUE to decimal value
                        - 0 to 255 (Default : initialize to picture)
  -fintrinsics=<value>  Intrinsics to be used without FUNCTION keyword
                        - ALL or intrinsic function name (,name,...)
  -ftrace               Generate trace code
                        - Executed SECTION/PARAGRAPH
  -ftraceall            Generate trace code
                        - Executed SECTION/PARAGRAPH/STATEMENTS
                        - Turned on by -debug
  -fsyntax-only         Syntax error checking only; don't emit any output
  -fdebugging-line      Enable debugging lines
                        - 'D' in indicator column or floating >>D
  -fsource-location     Generate source location code
                        - Turned on by -debug/-g/-ftraceall
  -fimplicit-init       Automatic initialization of the Cobol runtime system
  -fstack-check         PERFORM stack checking
                        - Turned on by -debug or -g
  -fsyntax-extension    Allow syntax extensions
                        - eg. Switch name SW1, etc.
  -fwrite-after         Use AFTER 1 for WRITE of LINE SEQUENTIAL
                        - Default : BEFORE 1
  -fmfcomment           '*' or '/' in column 1 treated as comment
                        - FIXED format only
  -fnotrunc             Allow numeric field overflow
                        - Non-ANSI behaviour
  -fodoslide            Adjust items following OCCURS DEPENDING
                        - Requires implicit/explicit relaxed syntax
  -fsingle-quote        Use a single quote (apostrophe) for QUOTE
                        - Default : double quote
  -frecursive-check     Check recursive program call
  -frelax-syntax        Relax syntax checking
                        - eg. REDEFINES position
  -foptional-file       Treat all files as OPTIONAL
                        - unless NOT OPTIONAL specified

Each file specified on the "cobc" command constitutes a 'Compilation
Unit'.  A compilation unit may be a single GNU COBOL program -- with or
without nested subprograms(see Independent vs Contained vs Nested Subprograms)
-- or multiple GNU COBOL programs, separated by "END
PROGRAM" or "END FUNCTION" marker lines, as appropriate.  See
Independent vs Contained vs Nested Subprograms, for some examples of
these marker lines.

A compilation unit may also be a C-language source program, recognized
as such by having a file extension of ".c" or an assembly-language
program, recognized by its file extension of ".s".  In such a case,
COBOL compilation of that file will be bypassed by the "cobc" command;
instead, the file will be passed directly to the C compiler or
assembler (executed automatically by "cobc").

A compilation unit may also be an object-code module (output from the C
compiler), recognized as such by having a file extension of ".o".  In
these situations, all compilation will be bypassed, and the object code
will be "bound" into the generated executable by the loader (an "ld"
command executed internally by the "cobc" command).

Precompiled object-code subprograms may be automatically located by the
GNU COBOL compiler and the loader by using the "LD_LIBRARY_PATH"
compilation-time environment variable (see Compilation Time Environment Variables).
If they are locatable through that
environment variable, they need not be named on the "cobc" command.

The collection of compilation units supplied on a single "cobc"
execution constitute a 'Compilation Group'.  All executable code
produced from a single compilation group will be collected together
into a single executable file, whose filename will be the same as that
of the first compilation unit specified on the "cobc" command.

The simplest mode of compilation is to generate a single executable
file from one or more GNU COBOL source files:

               "cobc -x mainprog.cbl sub1.cbl sub2.cbl"

The main program must be the first program found in the first
compilation unit ("mainprog.cbl").  The remainder of that compilation
unit as well as the rest of the files in the compilation group
("sub1.cbl" and "sub2.cbl") must be independent and/or contained
subprograms (see Independent vs Contained vs Nested Subprograms).

This command assumes that all source files are in the directory from
which the "cobc" command was executed.  You are, of course, free to
include full pathnames with any filename, if necessary.

With the "-x" switch on the compiler command, a single
directly-executable executable file (UNIX, Windows/Cygwin, OSX) or
"exe" file (Windows, Windows/MinGW) will be generated.  This executable
file has the compiled code for all COBOL programs contained within the
compilation group specified on the "cobc" command included in the
file.

Any subroutines or user-defined functions that weren't included in any
of the source files comprising the compilation group will be treated as
dynamically loadable subprograms (see Dynamic vs Static Subprograms).

Optionally, the "-o" switch may be used in addition to "-x" to specify
the name of the generated executable file.  If "-o" switch is not
specified, the filename of the 1st compilation unit will be used as the
name of the executable file.  The appropriate extension for the
generated file (".exe", on a Windows computer, for example) will be
added to the filename that is explicitly specified or implicitly
assumed for the output file.

Compilations may be performed to generate dynamically-loadable modules
(or dynamically-loadable libraries, as they are frequently called).
These compilations are performed by using the "-m" switch instead of
"-x" switch:

               "cobc -m mainprog.cbl sub1.cbl sub2.cbl"

When the "-m" switch is used, an operating-system specific
dynamically-loadable module is generated for each individual
compilation unit, using the filename of each compilation unit as the
it's module filename and either an extension of ".so" (UNIX,
Windows/Cygwin), "dylib" (OSX) or ".dll" (Windows, Windows/MinGW).

You may compile GNU COBOL subprograms into assembler source code which
can then be assembled and linked with a main program when that main
program is compiled.  To create such an assembler source file, compile
the subprogram(s) as follows:

                         "cobc -S sprog1.cbl"

The above generates an assembler source file named "sprog1.s".  If you
have multiple subprograms to compile this way, just string their
filenames out on the command -- each will be translated to it's own
assembler source file.

Later, when you wish to compile a calling program and combine any
needed assembly language subroutines in (as static subroutines -- see
Dynamic vs Static Subprograms), use a command such as this:

                    "cobc -x mainprog.cbl sprog1.s"

8.1.2. Compilation Time Environment Variables
---------------------------------------------

The following are the various environment variables that can play a
role in the compilation of GNU COBOL programs.

"COB_CC" *

     Set to the name of the C compiler you wish GNU COBOL to use.

     USE THIS FEATURE AT YOUR OWN RISK - YOU SHOULD ALWAYS USE THE C
     COMPILER YOUR GNU COBOL BUILD WAS GENERATED FOR

"COB_CFLAGS" *

     Set to any switches that you'd like to pass on to the C compiler
     from the "cobc" compiler (in addition to any that "cobc" will
     specify).

"COB_CONFIG_DIR" *

     Set to the path to the folder where GNU COBOL "config" files are
     kept.

"COB_COPY_DIR" *

     If copybooks your program needs are NOT stored in the same
     directory as your program, set this environment variable to the
     folder in which the copybooks may be found (IBM mainframe
     programmers will recognize this as "SYSLIB").

"COB_LDADD"

     Set to any additional linker switches (ld) that can specify where
     standard libraries that must be linked with the program can be
     found.  The default is "" (null).

"COB_LDFLAGS"

     Set to any linker/loader (ld) switches that you'd like to pass on
     to the C compiler from the "cobc" compiler (in addition to any
     that cobc will specify).

"COB_LIBS" *

     Set to any linker switches (ld) that specify where standard
     libraries that must be linked with the program can be found.

"COBCPY"

     This environment variable provides an additional means of
     specifying where copybooks may be found by the compiler (see also
     COB_COPY_DIR, above).

"LD_LIBRARY_PATH"

     If you are planning on using static-linked subroutine libraries,
     set this variable to the path of the directory containing your
     libraries.

"TMPDIR"
"TMP"

     Set to a directory/folder appropriate to create temporary files
     in.  The intermediate working files created by the compiler will
     be created here (and deleted once they're no longer needed).  The
     variable "TMPDIR" is checked for a valid path first; if that isn't
     set, then "TMP" is checked.

     On a Windows system, the "TMP" environment variable is normally
     set for you when you logon.  If you wish to use a different
     temporary folder, you may set "TMPDIR" yourself and have no fear
     of disrupting other Windows software that relies on TMP.

* These environment variables have default values established for them
  when the version of GNU COBOL you are using was built.  To see these
  default values, as well as other build-specific information, execute
  the command:

                                "cobc -i"

8.1.3. Locating Copybooks
-------------------------

The GNU COBOL compiler will attempt to locate copybooks by searching
for them in the following folders.  The search will occur in the
sequence shown below, and will terminate once a copybook is found.

  1. The folder named as the <library-name-1> on the "COPY" statement
     (see COPY).

  2. The folder in which the program being compiled resides.

  3. The folder named on the "-I" switch.

  4. Each of the folders named on the "COBCPY" compilation-time
     environment variable (see Compilation Time Environment Variables).

     A single folder may be named or multiple folders may be specified,
     separated by a system-appropriate delimiter character.  When
     multiple folders are specified, they will be searched in the order
     they are named on the environment variable.

     If the GNU COBOL compiler you are using was built to utilize a
     native Windows environment, use a semicolon (;) as the delimiter
     character.

     If, however, the GNU COBOL compiler was built for a Unix, OSX or
     Linux environment, or was built for a Windows environment
     utilizing either the Cygwin or MinGW Unix “emulators”, use a colon
     character (:) as the delimiter.

  5. The single folder specified on the COB_COPY_DIR environment
     variable.

As each of the above folders is searched for a copybook -- "COPY
XXXXXXXX.", for example -- the GNU COBOL compiler will attempt to
locate the copybook file by any of the following names, in the sequence
shown:

  1. XXXXXXXX.CPY

  2. XXXXXXXX.CBL

  3. XXXXXXXX.COB

  4. XXXXXXXX.cpy

  5. XXXXXXXX.cbl

  6. XXXXXXXX.cob

  7. XXXXXXXX

The "COPY" statement is case-sensitive on UNIX systems; "COPY
copybookname" and "COPY COPYBOOKNAME" will both fail to locate the
"CopyBookName" copybook on a UNIX system.

Windows implementations of GNU COBOL may, or may not, be similarly case
sensitive with regard to copybook names, depending upon the Windows
version and GNU COBOL build options -- it is safest to simply treat the
COPY command as case-sensitive in all environments.

It is possible, however, to automatically cause all "COPY" statements
to 'fold' the names of all copybooks to uppercase by specifying the
"-ffold-copy" switch with the "upper" option (i.e. "-fold-copy=upper")
to the GNU COBOL compiler.  Similarly, names could be folded to
lowercase by using the "lower" option (i.e. "-fold-copy=lower".  If
copybook libraries are maintained entirely using upper- or lower-case
filenames and extensions, either of these options will allow copybooks
to be found regardless of how the programmer entered their names on
"COPY" statements.

Case-folding may also be turned on and off within the program source
code using the CDF ">>SET" statement (see >>SET).

8.1.4. Compiler Configuration Files
-----------------------------------

GNU COBOL uses compiler configuration files to define various options
that will control the compilation process.  These configuration files
are specified using the "-conf" switch compilation switch and are found
in the folder defined by the "COB_CONFIG_DIR" compilation-time
environment variable (see Compilation Time Environment Variables).

The following is a verbatim listing of the "default" configuration file
(the one used if you don't specify the "-conf" switch), just to show
you the types of settings that may appear:

# COBOL compiler configuration                                  -*- sh -*-
# Value: any string
name: "GNU COBOL"

# Value: enum
standard-define                 0
#        CB_STD_OC = 0,
#        CB_STD_MF,
#        CB_STD_IBM,
#        CB_STD_MVS,
#        CB_STD_BS2000,
#        CB_STD_85,
#        CB_STD_2002

# Value: int
tab-width:                      8
text-column:                    72

# Value: 'mf', 'ibm'
#
assign-clause:                  mf

# If yes, file names are resolved at run time using
# environment variables.
# For example, given ASSIGN TO "DATAFILE", the file name will be
#  1. the value of environment variable 'DD_DATAFILE' or
#  2. the value of environment variable 'dd_DATAFILE' or
#  3. the value of environment variable 'DATAFILE' or
#  4. the literal "DATAFILE"
# If no, the value of the assign clause is the file name.
#
filename-mapping:               yes

# Alternate formatting of numeric fields
pretty-display:                 yes

# Allow complex OCCURS DEPENDING ON
complex-odo:                    no

# Allow REDEFINES to other than last equal level number
indirect-redefines:             no

# Binary byte size - defines the allocated bytes according to PIC
# Value:         signed  unsigned  bytes
#                ------  --------  -----
# '2-4-8'        1 -  4    same        2
#                5 -  9    same        4
#               10 - 18    same        8
#
# '1-2-4-8'      1 -  2    same        1
#                3 -  4    same        2
#                5 -  9    same        4
#               10 - 18    same        8
#
# '1--8'         1 -  2    1 -  2      1
#                3 -  4    3 -  4      2
#                5 -  6    5 -  7      3
#                7 -  9    8 -  9      4
#               10 - 11   10 - 12      5
#               12 - 14   13 - 14      6
#               15 - 16   15 - 16      7
#               17 - 18   17 - 18      8
#
binary-size:                    1-2-4-8

# Numeric truncation according to ANSI
binary-truncate:                yes

# Binary byte order
# Value: 'native', 'big-endian'
binary-byteorder:               big-endian

# Allow larger REDEFINES items
larger-redefines-ok:            no

# Allow certain syntax variations (eg. REDEFINES position)
relaxed-syntax-check:           no

# Perform type OSVS - If yes, the exit point of any currently
# executing perform is recognized if reached.
perform-osvs:                   no

# If yes, linkage-section items remain allocated
# between invocations.
sticky-linkage:                 no

# If yes, allow non-matching level numbers
relax-level-hierarchy:          no

# If yes, allow reserved words from the 85 standard
cobol85-reserved:               no

# Allow Hex 'F' for NUMERIC test of signed PACKED DECIMAL field
hostsign:                       no

# not-reserved:
# Value: Word to be taken out of the reserved words list
# (case independent)
# Words that are in the (proposed) standard but may conflict

# Dialect features
# Value: 'ok', 'archaic', 'obsolete', 'skip', 'ignore', 'unconformable'

alter-statement:                        obsolete
author-paragraph:                       obsolete
data-records-clause:                    obsolete
debugging-line:                         obsolete
eject-statement:                        skip
entry-statement:                        obsolete
goto-statement-without-name:            obsolete
label-records-clause:                   obsolete
memory-size-clause:                     obsolete
move-noninteger-to-alphanumeric:        error
multiple-file-tape-clause:              obsolete
next-sentence-phrase:                   archaic
odo-without-to:                         ok
padding-character-clause:               obsolete
section-segments:                       ignore
stop-literal-statement:                 obsolete
synchronized-clause:                    ok
top-level-occurs-clause:                ok
value-of-clause:                        obsolete

8.2. Running Programs
=====================

Once GNU COBOL programs have been compiled into either
directly-executable programs (created via the "-x" switch) or
dynamically-loadable libraries (created via the "-m" switch), those
programs may be executed from any shell environment.  The exact manner
in which the two are executed will differ, as described in the upcoming
sections.

8.2.1. Direct Execution
-----------------------

GNU COBOL programs compiled with the "-x" switch will be generated as
directly-executable programs.  For example, a native Windows or
Windows/MinGW build of GNU COBOL will generate an ".exe" file when the
"-x" switch switch is specified to the compiler.

On Unix, OSX, or Windows/Cygwin builds, the "-x" switch switch will
generate an executable binary file, usually with no particular
extension unless one is explicitly requested of the compiler via the
"-o" switch.

On a UNIX system this means the programs may be executed from a command
shell such as bash, csh, ksh and so forth.  When a GNU COBOL program
runs on a Windows system, it runs within a console window (i.e.
"cmd.exe").  OSX versions of GNU COBOL programs run within a
"terminal.app" window.

Interactions between the program and the user will take place using the
standard input, standard output and standard error streams.  Any screen
section I/O performed by the program will take place within the command
shell "window".

Direct program execution syntax is as follows:

                      "[path]program [arguments]"

For example:

                "/usr/local/printaccount ACCT=6625378"

                                  or

    "C:\Users\Me\Documents\Programs\printaccount.exe ACCT=6625378"

8.2.2. Executing Dynamically-Loadable Libraries
-----------------------------------------------

As discussed previously, dynamically-loadable libraries are created via
the compiler's "-m" switch.  Once so created, the program(s) in these
libraries are executed from the command line (via the GNU COBOL
"cobcrun" utility), or as dynamically-loadable subprograms.

8.2.2.1. cobcrun - Command-line Execution
.........................................

It is possible to generate executable modules for all GNU COBOL
programs, not just subprograms, by choosing to use the "-m" switch option
to specify the loader output format, even for main programs.

Some may prefer to compile their GNU COBOL main programs into these
dynamically-loadable modules in the interests of using the same general
compilation command for all programs without having to think "Is it a
main program or a subprogram?".

Main programs compiled in this manner should be executed as follows:

                  "[path]cobcrun program [arguments]"

Do not specify the ".so" or ".dll" extension on the program name.  The
program value must exactly match the primary entry-point name of the
main program (including upper- and lower-case letters), unless you are
planning on using "Call Folding" (see Dynamically Loaded Subprograms).

The general usage and syntax of cobcrun is as follows:

Usage: cobcrun PROGRAM [param ...]
or   : cobcrun --help (-h)
       Print this help
or   : cobcrun --version (-V)
       Print version information
or   : cobcrun --info (-i)
       Print build information

Here are two examples of using "cobcrun".  First, on a Unix, OSX or
Windows/Cygwin system:

     cd /usr/local
     cobcrun printaccount acct=6625378

Or, on a Native Windows or Windows/MinGW system:

     cd C:\Users\Me\Documents\Programs
     cobcrun printaccount.exe acct=6625378

Note how the "cobcrun" command does not allow a path to be specified
with the program name -- the directory in which the programs
dynamically loadable module exists must either be the current directory
or must be defined in the current PATH.

8.2.2.2. Dynamically Loaded Subprograms
.......................................

Dynamically-loaded subprograms are executed (from a COBOL syntax point
of view) just like any other subprograms.  What makes them unique,
however, is that they are loaded into memory only when they are
actually used the first time during the execution of a program.

When a dynamically-loadable module needs to be loaded (because it is
not already in memory from a previous subprogram execution), the
dynamically-loadable library will be sought in the same directory from
which the main program was loaded.  If it cannot be found there, each
directory named in the "PATH" run-time environment variable (see Run Time Environment Variables)
will be searched.  If it was not located
in any of those directories, the library specified by the "COB_LIBRARY_PATH"
run-time environment variable will be searched.  Finally, if it still
cannot be located, execution will be terminated with an error message
("libcob: Cannot find module 'xxxxxxxx'").

The process of locating dynamically-loadable modules is case-sensitive
on UNIX systems; "CALL "dynsub"" and "CALL "DYNSUB"" will both fail to
locate the "DynSub.so" library on a UNIX system.

Windows implementations of GNU COBOL may, or may not, be similarly case
sensitive with regard to library names, depending upon the Windows
version and GNU COBOL build options -- it is safest to simply treat
library names as case-sensitive in all environments.

It is possible, however, to automatically cause all library names to
'fold' to uppercase by specifying the "-ffold-call" switch with the
"upper" option (i.e. "-fold-call=upper") to the GNU COBOL compiler.
Similarly, library names could be folded to lowercase by using the
"lower" option (i.e. "-fold-call=lower".  If libraries are maintained
entirely using upper- or lower-case filenames, either of these options
will allow libraries to be found regardless of how the programmer
entered their names on "CALL" statements.

See Sub-Programming, for a complete discussion of sub-programming.

8.2.3. Run Time Environment Variables
-------------------------------------

The following is a list of the various environment variables that can
play a role in the execution of GNU COBOL programs.

"COB_DISPLAY_WARNINGS"

     If set to a value of "Y", any run-time warnings (such as noting
     the implicit closing of open files when a "GOBACK" statement
     (see GOBACK) or "STOP" statement (see STOP) with the "RUN"
     option is executed) will be displayed.  Any other value for this
     environment variable (including not setting the variable at all)
     will suppress such messages.

"COB_LIBRARY_PATH"

     At runtime, GNU COBOL will attempt to locate and load any
     application dynamically-loadable libraries using from the
     directory in which the program executable was found or, if it
     wasn't found there, using the "PATH" environment variable.  If
     these library files could be somewhere else, specify the directory
     path using this variable.

"COB_LOAD_CASE"

     If set to either "UPPER" or "LOWER", this environment variable
     will internally convert referenced entry-point names to either
     upper- or lower-case before initiating searches for
     dynamically-loadable modules.  The "UPPER" and "LOWER" values of
     the environment variable are actually case-insensitive.

"COB_PHYSICAL_CANCEL"

     If set to "Y", "y" or "1", a "CANCEL" statement (see CANCEL)
     will physically unload a subprogram dynamically-loadable module.

     If set to anything else, a "CANCEL" statement (see CANCEL)
     logically unloads a module so that subsequent use will
     re-initialize the module as if it had actually been reloaded, but
     the overhead of actually reloading the module will be avoided.

"COB_PRE_LOAD"

     If set to any non-null value, this variable will cause all
     dynamically-loadable libraries to be loaded when the program
     begins execution (rather than searching for and loading the module
     upon first use).

"COB_SET_DEBUG"

     If a "USE FOR DEBUGGING" (see DECLARATIVES) section exists,
     the code within it will be disabled unless this environment
     variable is set to a value of "Y", "y" or "1".

"COB_SET_TRACE"

     If the "-ftrace" switch or "-ftraceall" switch was used when the
     program was compiled, setting this environment variable to a value
     of "Y" will activate the trace at the point the program begins
     execution.  Setting this environment variable to any other value
     (or never setting it to ANY value) will disable tracing.  See the
     "READY TRACE" statement (see READY TRACE) and "RESET TRACE"
     statement (see RESET TRACE) for additional ways to control
     tracing.

"COB_SCREEN_ESC"

     If set to any non-blank value, this variable allows a "ACCEPT
     screen-data-item" statement (see ACCEPT screen-data-item) to
     detect the "Esc" key.

"COB_SCREEN_EXCEPTIONS"

     Setting this variable to any non-blank value will allow the
     "ACCEPT screen-data-item" statement (see ACCEPT screen-data-item)
     to detect the pressing of the "Esc", "PgUp"
     and "PgDn" keys.

"COB_SORT_MEMORY"

     The value of this variable (an integer) will be used to define how
     much memory will be allocated for use in sorting.  If the value is
     1048576 or greater, that value will be used "as is" as the amount
     of memory (in bytes) to allocate.  If the value is less than
     1048576, the value will spefify how many MB of memory will be
     allocated.  The default sort memory amount is 128 MB.

"COB_SWITCH_n"

     (n=0 to 15); These environment variables correspond to "SWITCH-0"
     through "SWITCH-15", defined in the "SPECIAL-NAMES" (see
     SPECIAL-NAMES) paragraph.  Setting them to "ON" will activate
     them; any other value turns them off.

"COB_SYNC"

     If set to a value of upper- or lowercase "p", this variable will
     force a file commit every time a file is written to (ensuring that
     data is immediately written to the file rather than retained in
     memory until a future commit occurs).  This will slow-down update
     access to files, but will provide for better integrity in the
     event of a program failure.

"COB_TRACE_FILE"

     If set to any non-null value, this environment variable specifies
     the file to which all "-ftrace" switch and "-ftraceall" switch
     output will be written.

     If this is NOT set to a value, all "-ftrace" switch and
     "-ftraceall" switch output will be written to STDERR, where it may
     be piped via a "2> filename" on the command that executes the
     program.

"DB_HOME"

     If your GNU COBOL build uses the Berkeley Database (BDB) package,
     use this environment variable to specify the folder in which the
     lock management files to be associated with all non-SORT files
     opened by the program will be stored.  "ORGANIZATION INDEXED"
     (see ORGANIZATION INDEXED) files will also have their data
     file allocated in the folder pointed to by this environment
     variable, if it exists..  Having this variable defined will
     activate record locking features on the "READ" statement (see
     READ), "REWRITE" statement (see REWRITE) and "WRITE"
     statement (see WRITE).  Even with DB_HOME, locking will not
     work with "ORGANIZATION SEQUENTIAL" (see ORGANIZATION SEQUENTIAL),
     "ORGANIZATION LINE SEQUENTIAL" (see ORGANIZATION LINE SEQUENTIAL)
     or ORGANIZATION RELATIVE files with GNU COBOL
     builds created for Windows/MinGW.  "ORGANIZATION INDEXED" locks
     will work with Windows/MinGW + BDB and all locks will work for all
     file organizations with UNIX GNU COBOL builds.

"PATH"

     The GNU COBOL "bin" directory should be defined in the PATH.

"TMPDIR"
"TMP"
"TEMP"

     One of these environment variables must be set to a
     directory/folder appropriate to create temporary files in.  They
     will be checked in the order shown.  This will be used by the
     "SORT" statement (see SORT) and "MERGE" statement (see
     MERGE) to create temporary work files.  You may also use this
     folder for any temporary files your application may require.

8.2.4. Program Arguments
------------------------

Regardless of the manner in which a main program is executed (i.e.
directly or via "cobcrun"), any arguments specified to the program may
be retrieved via any of the following:

   * "ACCEPT FROM COMMAND-LINE" (see ACCEPT FROM COMMAND-LINE)

   * "PROCEDURE DIVISION CHAINING" (see PROCEDURE DIVISION CHAINING)

8.3. Built-In System Subroutines
================================

There are a number of built-in system subroutines included with GNU
COBOL.  Generally, these routines are intended to match those available
in Micro Focus COBOL (CBL_...) or ACUCOBOL (C$...).

These routines, all executed via their UPPERCASE NAMES via the "CALL"
statement (see CALL), are capable of performing the following
Functions:

   * Changing the current directory

   * Copying files

   * Creating a directory

   * Creating, Opening, Closing, Reading and Writing byte-stream files

   * Deleting directories (folders)

   * Deleting files

   * Determining how many arguments were passed to a subroutine

   * Getting file information (size and last-modification date/time)

   * Getting the length (in bytes) of an argument passed to a
     subroutine

   * Justifying a field left-, right- or center-aligned

   * Moving files (a destructive "copy")

   * Putting the program 'to sleep', specifying the sleep time in
     seconds

   * Putting the program 'to sleep', specifying the sleep time in
     nanoseconds; CAVEAT: although you'll express the time in
     nanoseconds, Windows systems will only be able to sleep at a
     millisecond granularity

   * Retrieving information about the currently-executing program

   * Submitting a command to the shell environment appropriate for the
     version of GNU COBOL you are using for execution

Early versions of Micro Focus COBOL allowed programmers to access
various runtime library routines by using a single two-digit
hexadecimal number as the entry-point name.  These were known as
call-by-number routines.  Over time, Micro Focus COBOL evolved,
replacing most of the call-by-number routines with ones accessible
using a more conventional call-by-name technique.

Most of the call-by-number routines have evolved into even more
powerful call-by-name routines, many of which are supported by GNU
COBOL.

Some of the original call-by-number routines never evolved call-by-name
equivalents; GNU COBOL supports some of these routines.

The following sections describe the various built-in subroutines.  ALL
SUBROUTINE ARGUMENTS ARE MANDATORY EXCEPT WHERE EXPLICITLY NOTED TO THE
CONTRARY.  Any subroutine returning a value to the "RETURN-CODE"
special register (see Special Registers) could utilize the
"RETURNING" clause on the "CALL" statement to return the result back to
the full-word binary data item of your choice.

8.3.1. C$CALLEDBY
-----------------

                  C$CALLEDBY Built-In Subroutine Syntax
=======================================================================

 CALL "C$CALLEDBY" USING prog-name-area
 ~~~~              ~~~~~

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

This routine returns the name of the program that called the
currently-executing program.  The program name will be returned,
left-justified and space filled, in the specified <prog-name-area>
argument, which should be a "PIC X" elementary item or a group item.
If <prog-name-area> is too small to receive the entire program name,
the program name value will be truncated (on the right) to fit.

The "RETURN-CODE" special register (see Special Registers) will be
set to one of the following values:

-1   An error occurred.  The <prog-name-area> contents will be
     unchanged.

0    The program calling "C$CALLEDBY" was not called by any other
     program (in other words, it is a main program).  The
     <prog-name-area> contents will be set entirely to spaces.

1    The program calling "C$CALLEDBY" was indeed called by another
     program, and that program's name has been saved in
     <prog-name-area>.

8.3.2. C$CHDIR
--------------

                   C$CHDIR Built-In Subroutine Syntax
=======================================================================

 CALL "C$CHDIR" USING directory-path, result
 ~~~~           ~~~~~

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

This routine makes <directory-path> (an alphanumeric literal or
identifier) the current directory.

The return code of the operation is returned both in the <result>
argument (any non-edited numeric identifier) as well as in the
"RETURN-CODE" special register (see Special Registers).   The
return code of the operation will be either 0=Success or 128=failure.

The directory change remains in effect until the program terminates (in
which the original current directory at the time the program was
started will be automatically restored) or until another "C$CHDIR" or a
"CBL_CHANGE_DIR" built-in system subroutine (see CBL_CHANGE_DIR) is
executed.

8.3.3. C$COPY
-------------

                    C$COPY Built-In Subroutine Syntax
=======================================================================

 CALL "C$COPY" USING src-file-path, dest-file-path, 0
 ~~~~          ~~~~~

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

Use this subroutine to copy file <src-file-path> to <dest-file-path> as
if it were done via the "CP" (Unix/OSX) or "COPY" (Windows) command.

Both file path arguments may be alphanumeric literals or identifiers.

The third argument is required, but is unused.

If the attempt to copy the file fails (for example, it or the
destination directory doesn't exist), the "RETURN-CODE" special register (see
Special Registers) will be set to 128; on successful completion it
will be set to 0.

8.3.4. C$DELETE
---------------

                   C$DELETE Built-In Subroutine Syntax
=======================================================================

 CALL "C$DELETE" USING file-path, 0
 ~~~~            ~~~~~

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

This routine deletes the file specified by the <file-path> argument (an
alphanumeric literal or identifier) just as if that were done using the
"RM" (Unix/OSX) or "ERASE" (Windows) command.

The second argument is required, but is unused.

If the attempt to delete the file fails (for example, it doesn't
exist), the "RETURN-CODE" special register (see Special Registers)
will be set to 128; on successful completion it will be set to 0.

8.3.5. C$FILEINFO
-----------------

                  C$FILEINFO Built-In Subroutine Syntax
=======================================================================

 CALL "C$FILEINFO" USING file-path, file-info
 ~~~~              ~~~~~

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

With this routine you may retrieve the size of the file specified as
the <file-path> argument (an alphanumeric literal or identifier) and
the date/time that file was last modified.  File size information may
not be available in the particular GNU COBOL build / Operating System
combination you are using and may therefore always be returned as zero.
The information is returned to the <file-info> argument, which is
defined as the following 16-byte area:

     01  File-Info.
         05 File-Size-In-Bytes  PIC 9(18) COMP.
         05 Mod-YYYYMMDD        PIC 9(8)  COMP. *> Modification Date
         05 Mod-HHMMSS00        PIC 9(8)  COMP. *> Modification Time

The last two decimal digits in the modification time will always be
00.

If the subroutine is successful, a value of 0 will be returned in the
"RETURN-CODE" special register (see Special Registers).  Failure to
retrieve the needed statistics on the file will cause a "RETURN-CODE"
special register value of 35 to be passed back.  Supplying less than
two arguments will generate a 128 "RETURN-CODE" special register value.

8.3.6. C$GETPID
---------------

                   C$GETPID Built-In Subroutine Syntax
=======================================================================

 CALL "C$GETPID"
 ~~~~

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

Use this subroutine to return the PID (process ID) of the executing GNU
COBOL program.  The PID value is returned into the "RETURN-CODE"
special register (see Special Registers).

As you can see, there are no arguments to this routine.

8.3.7. C$JUSTIFY
----------------

                  C$JUSTIFY Built-In Subroutine Syntax
=======================================================================

 CALL "C$JUSTIFY" USING data-item, "justification-type"
 ~~~~             ~~~~~

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

Use C$JUSTIFY to left, right or center-justify an alphabetic,
alphanumeric or numeric edited data-item.  The optional
justification-type argument indicates the type of the justification to
be performed.  The value of that argument will be interpreted as
follows:

   * If it begins with a capital "C", the value will be centered

   * If it begins with a capital "R", the value will be
     right-justified, space-filled to the left

   * If it begins with a capital "L", the value will be left-justified,
     space-filled to the right

   * If it begins with anything else, or is absent, it will be treated
     as if it is present and begins with a capital "R"

8.3.8. C$MAKEDIR
----------------

                  C$MAKEDIR Built-In Subroutine Syntax
=======================================================================

 CALL "C$MAKEDIR" USING dir-path
 ~~~~             ~~~~~

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

With this routine you may create a new directory -- the name of which
is supplied as the <dir-path> argument (an alphanumeric literal or
identifier).

Only the lowest-level directory (last) in the specified path can be
created -- all others must already exist.  This subroutine will NOT
behave as a "mkdir -p" (Unix) or "mkdir /p" (Windows).

The "RETURN-CODE" special register (see Special Registers) will be
set to the return code of the operation; the value will be either
0=Success or 128=failure.

8.3.9. C$NARG
-------------

                    C$NARG Built-In Subroutine Syntax
=======================================================================

 CALL "C$NARG" USING arg-count-result
 ~~~~          ~~~~~

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

This subroutine returns the number of arguments passed to the program
that calls it back to in the numeric field <arg-count-result>.  When
called from within a user-defined function, a value of one (1) is
returned if any arguments were passed to the function or a zero (0)
otherwise.

When called from a main program, the returned value will always be 0.

8.3.10. C$PARAMSIZE
-------------------

                 C$PARAMSIZE Built-In Subroutine Syntax
=======================================================================

 CALL "C$PARAMSIZE" USING argument-number
 ~~~~               ~~~~~

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

This subroutine returns the size (in bytes) of the subroutine argument
supplied using the <argument-number> parameter (a numeric literal or
data item).

The size is returned in the "RETURN-CODE" special register (see
Special Registers).

If the specified argument does not exist, or an invalid argument number
is specified, a value of 0 is returned.

8.3.11. C$PRINTABLE
-------------------

                 C$PRINTABLE Built-In Subroutine Syntax
=======================================================================

 CALL "C$PRINTABLE" USING data-item [ , char ]
 ~~~~               ~~~~~

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

The "C$PRINTABLE" subroutine converts the contents of the data-item
specified as the first argument to printable characters.  Those
characters that are deemed printable (as defined by the characterset
used by <data-item>) will remain unchanged, while those that are NOT
printable will be converted to the character specified as the second
argument.

If no <char> argument is provided, a period (".") will be used.

8.3.12. C$SLEEP
---------------

                   C$SLEEP Built-In Subroutine Syntax
=======================================================================

 CALL "C$SLEEP" USING seconds-to-sleep
 ~~~~           ~~~~~

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

"C$SLEEP" puts the program to sleep for the specified number of
seconds.  The <seconds-to-sleep> argument may be a numeric literal or
data item.

Sleep times less than 1 will be interpreted as 0, which immediately
returns control to the calling program without any sleep delay.

8.3.13. C$TOLOWER
-----------------

                  C$TOLOWER Built-In Subroutine Syntax
=======================================================================

 CALL "C$TOLOWER" USING data-item, BY VALUE convert-length
 ~~~~             ~~~~~               ~~~~~

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

This routine will converts the <convert-length> (a numeric literal or
data item) leading characters of <data-item> (an alphanumeric
identifier) to lower-case.

The <convert-length> argument must be specified "BY VALUE" (see
CALL).
 Any characters in <data-item> after the <convert-length>
point will remain unchanged.

If <convert-length> is negative or zero, no conversion will be
performed.

8.3.14. C$TOUPPER
-----------------

                  C$TOUPPER Built-In Subroutine Syntax
=======================================================================

 CALL "C$TOUPPER" USING data-item, BY VALUE convert-length
 ~~~~             ~~~~~               ~~~~~

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

This routine will converts the <convert-length> (a numeric literal or
data item) leading characters of <data-item> (an alphanumeric
identifier) to upper-case.

The <convert-length> argument must be specified "BY VALUE" (see
CALL).
 Any characters in <data-item> after the <convert-length>
point will remain unchanged.

If <convert-length> is negative or zero, no conversion will be
performed.

8.3.15. CBL_AND
---------------

                   CBL_AND Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_AND" USING item-1, item-2, BY VALUE byte-length
 ~~~~           ~~~~~                    ~~~~~

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

Old    Old    New      This subroutine performs a bit-by-bit logical AND
Arg 1  Arg 2  Arg 2    operation between the left-most 8*<byte-length>
Bit    Bit    Bit      corresponding bits of <item-1> and <item-2>,
=====  =====  =====    storing the resulting bit string into <item-2>.
0      0      0        The truth table shown to the left documents the
0      1      0        AND process.
1      0      0        The <item-1> argument may be an alphanumeric
1      1      1        literal or a data item and <item-2> must be a
                       data item.  The length of both <item-1> and
                       <item-2> must be at least 8*<byte-length>.

The <byte-length> argument may be a numeric literal or data item, and
must be specified using "BY VALUE" (see CALL).

Any bits in <item-2> after the 8*<byte-length> point will be
unaffected.

A result of zero will be passed back in the "RETURN-CODE" special
register (see Special Registers).

8.3.16. CBL_CHANGE_DIR
----------------------

                CBL_CHANGE_DIR Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_CHANGE_DIR" USING directory-path
 ~~~~                  ~~~~~

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

This routine makes <directory-path> (an alphanumeric literal or
identifier) the current directory.

The return code of the operation, which will be either 0=Success or
128=failure, is returned in the "RETURN-CODE" special register (see
Special Registers).

The directory change remains in effect until the program terminates (in
which the original current directory at the time the program was
started will be automatically restored) or until another
"CBL_CHANGE_DIR" or a "C$CHDIR" built-in system subroutine (see
C$CHDIR) is executed.

8.3.17. CBL_CHECK_FILE_EXIST
----------------------------

             CBL_CHECK_FILE_EXIST Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_CHECK_FILE_EXIST" USING file-path, file-info
 ~~~~                        ~~~~~

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

With this routine you may retrieve the size of the file specified as
the <file-path> argument (an alphanumeric literal or identifier) and
the date/time that file was last modified.  File size information may
not be available in the particular GNU COBOL build / Operating System
combination you are using and may therefore always be returned as
zero.

The information is returned to the <file-info> argument, which is
defined as the following 16-byte area:

     01  file-info.
         05 File-Size-In-Bytes  PIC 9(18)  COMP.
         05 Mod-DD              PIC 9(2)   COMP.  *> Modification Time
         05 Mod-MO              PIC 9(2)   COMP.
         05 Mod-YYYY            PIC 9(4)   COMP.  *> Modification Date
         05 Mod-HH              PIC 9(2)   COMP.
         05 Mod-MM              PIC 9(2)   COMP.
         05 Mod-SS              PIC 9(2)   COMP.
         05 FILLER              PIC 9(2)   COMP.  *> Always 00

If the subroutine is successful, a value of 0 will be returned in the
"RETURN-CODE" special register (see Special Registers).  Failure to
retrieve the needed statistics on the file will cause a "RETURN-CODE"
special register value of 35 to be passed back.  Supplying less than
two arguments will generate a 128 "RETURN-CODE" special register value.

8.3.18. CBL_CLOSE_FILE
----------------------

                CBL_CLOSE_FILE Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_CLOSE_FILE" USING file-handle
 ~~~~                  ~~~~~

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

The "CBL_CLOSE_FILE" subroutine closes a bytestream file previously
opened by either the "CBL_OPEN_FILE" built-in system subroutine (see
CBL_OPEN_FILE) or "CBL_CREATE_FILE" built-in system subroutine (see
CBL_CREATE_FILE) subroutines.

If the file defined by the <file-handle> argument (a "PIC X(4) USAGE
COMP-X" data item) was opened for output, an implicit "CBL_FLUSH_FILE"
built-in system subroutine (see CBL_FLUSH_FILE) will be performed
before the file is closed.

If the subroutine is successful, a value of 0 will be returned in the
"RETURN-CODE" special register (see Special Registers).  Failure
will cause a "RETURN-CODE" special register value of -1 to be passed
back.

8.3.19. CBL_COPY_FILE
---------------------

                CBL_COPY_FILE Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_COPY_FILE" USING src-file-path, dest-file-path
 ~~~~                 ~~~~~

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

Use this subroutine to copy file <src-file-path> to <dest-file-path> as
if it were done via the "CP" (Unix/OSX) or "COPY" (Windows) command.

Both arguments may be alphanumeric literals or identifiers.

If the attempt to copy the file fails (for example, it or the
destination directory doesn't exist), the "RETURN-CODE" special register (see
Special Registers) will be set to 128; on successful completion it
will be set to 0.

8.3.20. CBL_CREATE_DIR
----------------------

                CBL_CREATE_DIR Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_CREATE_DIR" USING dir-path
 ~~~~                  ~~~~~

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

With this routine you may create a new directory -- the name of which
is supplied as the <dir-path> argument (an alphanumeric literal or
identifier).

Only the lowest-level directory (last) in the specified path can be
created -- all others must already exist.  This subroutine will NOT
behave as a "mkdir -p" (Unix) or "mkdir /p" (Windows).

The "RETURN-CODE" special register (see Special Registers) will be
set to the return code of the operation; the value will be either
0=Success or 128=failure.

8.3.21. CBL_CREATE_FILE
-----------------------

               CBL_CREATE_FILE Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_CREATE_FILE" USING file-path, 2, 0, 0, file-handle
 ~~~~                   ~~~~~

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

The "CBL_CREATE_FILE" subroutine creates the new file specified using
the file-path argument and opens it for output as a byte-stream file
usable by "CBL_WRITE_FILE" built-in system subroutine (see
CBL_WRITE_FILE).

Arguments 2, 3 and 4 should be coded as the constant values shown.
"CBL_CREATE_FILE" is actually a special-case of the "CBL_OPEN_FILE"
built-in system subroutine (see CBL_OPEN_FILE) routine -- see that
routine for a description of the meanings of arguments 2, 3 and 4.

A <file-handle> ("PIC X(4) USAGE COMP-X)" will be returned, for use on
any subsequent "CBL_WRITE_FILE" built-in system subroutine (see
CBL_WRITE_FILE) or "CBL_CLOSE_FILE" built-in system subroutine (see
CBL_CLOSE_FILE) calls.

The success or failure of the subroutine will be reported back in the
"RETURN-CODE" special register (see Special Registers), with a
value of -1 indicating an invalid argument and a value of 0 indicating
success.

8.3.22. CBL_DELETE_DIR
----------------------

                CBL_DELETE_DIR Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_DELETE_DIR" USING dir-path
 ~~~~                  ~~~~~

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

This subroutine deletes an empty directory.

The only argument -- <dir-path> (an alphanumeric literal or identifier)
-- is the name of the directory to be deleted.

Only the lowest-level directory (last) in the specified path will be
deleted, and that directory must be empty to be deleted.

The "RETURN-CODE" special register (see Special Registers) will be
set to the return code of the operation; the value will be either
0=Success or 128=failure.

8.3.23. CBL_DELETE_FILE
-----------------------

               CBL_DELETE_FILE Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_DELETE_FILE" USING file-path
 ~~~~                   ~~~~~

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

This routine deletes the file specified by the <file-path> argument (an
alphanumeric literal or identifier) just as if that were done using the
"RM" (Unix/OSX) or "ERASE" (Windows) command.

If the attempt to delete the file fails (for example, it doesn't
exist), the "RETURN-CODE" special register (see Special Registers)
will be set to 128; on successful completion it will be set to 0.

8.3.24. CBL_EQ
--------------

                    CBL_EQ Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_EQ" USING item-1, item-2, BY VALUE byte-length
 ~~~~          ~~~~~                    ~~~~~

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

Old    Old    New      This subroutine performs a bit-by-bit comparison
Arg 1  Arg 2  Arg 2    between the left-most 8*<byte-length>
Bit    Bit    Bit      corresponding bits of <item-1> and <item-2>,
=====  =====  =====    storing the resulting bit string into <item-2>.
0      0      1        The truth table shown to the left documents the
0      1      0        EQ process.
1      0      0        The <item-1> argument may be an alphanumeric
1      1      1        literal or a data item and <item-2> must be a
                       data item.  The length of both <item-1> and
                       <item-2> must be at least 8*<byte-length>.

The <byte-length> argument may be a numeric literal or data item, and
must be specified using "BY VALUE" (see CALL).

Any bits in <item-2> after the 8*<byte-length> point will be
unaffected.

A result of zero will be passed back in the "RETURN-CODE" special
register (see Special Registers).

8.3.25. CBL_ERROR_PROC
----------------------

                CBL_ERROR_PROC Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_ERROR_PROC" USING function, program-pointer
 ~~~~                  ~~~~~

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

This routine registers a general error-handling routine.

The <function> argument must be a numeric literal or a 32-bit binary
data item ("USAGE BINARY-LONG", for example) with a value of 0 or 1.  A
value of 0 means that you will be registering ("installing") an error
procedure while a value of 1 indicates you're deregistering
("uninstalling") a previously-installed error procedure.

The <program-pointer> must be a data item with a "USAGE" (see
USAGE) of "PROGRAM-POINTER" containing the address of your error
procedure.  This item should be given a value using the "SET
Program-Pointer" statement (see SET Program-Pointer).  If the error
procedure is written in GNU COBOL, it must be a subroutine, not a
user-defined function.

A success (0) or failure (non-0) result will be passed back in the
"RETURN-CODE" special register (see Special Registers).

A custom error procedure will trigger when a runtime error condition is
encountered.  An error procedure may be registered by a main program or
a subprogram, but regardless of from where it was registered, it
applies to the overall program compilation group  and will trigger when
a runtime error occurs anywhere in the executable program.  If the
error procedure was defined by a subprogram, that program must be
loaded at the time the error procedure is executed.

An error procedure may be used to take whatever actions might be
warranted to display additional information or to gracefully close down
work in progress, but it cannot prevent the termination of program
execution; should the error procedure not issue its own "STOP RUN",
control will return back to the standard error routine when the error
procedure exits.

The code within the handler will be executed and -- once the handler
issues a "return", if it was written in C, or an "EXIT PROGRAM"
statement (see EXIT) or "GOBACK" statement, if it was written in
GNU COBOL, the system-standard error handling routine will be
executed.

Only one user-defined error procedure may be in effect at any time.

The following is a sample GNU COBOL program that registers an error
procedure.  The output of that program is shown as well.  As as you can
see, the error handler's messages appear followed by the standard GNU
COBOL message.

     1.     IDENTIFICATION DIVISION.
     2.     PROGRAM-ID. DemoERRPROC.
     3.     ENVIRONMENT DIVISION.
     4.     DATA DIVISION.
     5.     WORKING-STORAGE SECTION.
     6.     01  Err-Proc-Address            USAGE PROGRAM-POINTER.
     7.     PROCEDURE DIVISION.
     8.     S1.
     9.         DISPLAY 'Program is starting'
     10.        SET Err-Proc-Address TO ENTRY 'ErrProc'
     11.        CALL 'CBL_ERROR_PROC' USING 0, Err-Proc-Address
     12.        CALL 'Tilt' *> THIS DOESN'T EXIST!!!!
     13.        DISPLAY 'Program is stopping'
     14.        STOP RUN
     15.        .
     16.    END PROGRAM DemoERRPROC.
     17.
     18.    IDENTIFICATION DIVISION.
     19.    PROGRAM-ID. ErrProc.
     20.    PROCEDURE DIVISION.
     21.    000-Main.
     22.        DISPLAY 'Error: ' FUNCTION EXCEPTION-LOCATION
     23.        DISPLAY '       ' FUNCTION EXCEPTION-STATEMENT
     24.        DISPLAY '       ' FUNCTION EXCEPTION-FILE
     25.        DISPLAY '       ' FUNCTION EXCEPTION-STATUS
     26.        DISPLAY '*** Returning to Standard Error Routine ***'
     27.        EXIT PROGRAM
     28.        .
     29.    END PROGRAM ErrProc.

When executed, this sample program generates the following console
output.

     E:\Programs\Demos>demoerrproc
     Program is starting
     Error: DemoERRPROC; S1; 12
            CALL
            00
            EC-PROGRAM-NOT-FOUND
     *** Returning to Standard Error Routine ***
     DEMOERRPROC.cbl: 27: libcob: Cannot find module 'Tilt'

     E:\Programs\Demos>

8.3.26. CBL_EXIT_PROC
---------------------

                CBL_EXIT_PROC Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_EXIT_PROC" USING function, program-pointer
 ~~~~                 ~~~~~

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

This routine registers a general exit-handling routine.

The <function> argument must be a numeric literal or a 32-bit binary
data item ("USAGE BINARY-LONG", for example) with a value of 0 or 1.  A
value of 0 means that you will be registering ("installing") an exit
procedure while a value of 1 indicates you're deregistering
("uninstalling") a previously-installed exit procedure.

The <program-pointer> must be a data item with a "USAGE" (see
USAGE) of "PROGRAM-POINTER" containing the address of your exit
procedure.

A success (0) or failure (non-0) result will be passed back in the
"RETURN-CODE" special register (see Special Registers).

An exit procedure, once registered, will trigger whenever a "STOP RUN"
statement (see STOP) or a "GOBACK" statement (see GOBACK) is
executed anywhere in the program.  The exit procedure may execute
whatever code is desired to undertake an orderly shutdown of the
program.  Once the exit procedure terminates by executing an "EXIT
PROGRAM" statement (see EXIT) or a "GOBACK" statement, the
system-standard program termination routine will be executed.

Only one user-defined exit procedure may be in effect at any time.

The following is a sample GNU COBOL program that registers an exit
procedure.  The output of that program is shown as well.

     IDENTIFICATION DIVISION.
     PROGRAM-ID. demoexitproc.
     DATA DIVISION.
     WORKING-STORAGE SECTION.
     01  Exit-Proc-Address           USAGE PROGRAM-POINTER.
     PROCEDURE DIVISION.
     000-Register-Exit-Proc.
         SET Exit-Proc-Address TO ENTRY "ExitProc"
         CALL "CBL_EXIT_PROC" USING 0, Exit-Proc-Address
         IF RETURN-CODE NOT = 0
             DISPLAY 'Error: Could not register Exit Procedure'
         END-IF
         .
     099-Now-Test-Exit-Proc.
         DISPLAY
             'Executing a STOP RUN...'
         END-DISPLAY
         GOBACK
         .
     END PROGRAM demoexitproc.

     IDENTIFICATION DIVISION.
     PROGRAM-ID. ExitProc.
     DATA DIVISION.
     WORKING-STORAGE SECTION.
     01  Display-Date                PIC XXXX/XX/XX.
     01  Display-Time                PIC XX/XX/XX.
     01  Now                         PIC X(8).
     01  Today                       PIC X(8).
     PROCEDURE DIVISION.
     000-Main.
         DISPLAY '*** STOP RUN has been executed ***'
         ACCEPT Today FROM DATE YYYYMMDD
         ACCEPT Now   FROM TIME
         MOVE Today TO Display-Date
         MOVE Now   TO Display-Time
         INSPECT Display-Time REPLACING ALL '/' BY ':'
         DISPLAY '***    ' Display-Date '  ' Display-Time '    ***'
         GOBACK
         .
     END PROGRAM ExitProc.

8.3.27. CBL_FLUSH_FILE
----------------------

                CBL_FLUSH_FILE Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_FLUSH_FILE" USING file-handle
 ~~~~                  ~~~~~

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

In Micro Focus COBOL, calling this subroutine flushes any as-yet
unwritten memory buffers for the (output) file whose file-handle is
specified as the argument to disk.

This routine is non-functional in GNU COBOL.  It exists only to provide
compatibility for applications that may have been developed for Micro
Focus COBOL.

8.3.28. CBL_GET_CSR_POS
-----------------------

               CBL_GET_CSR_POS Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_GET_CSR_POS" USING cursor-locn-buffer
 ~~~~                   ~~~~~

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

This subroutine will retrieve the current cursor location on the
screen, returning a 2-byte value into the supplied
<cursor-locn-buffer>.  The first byte of <cursor-locn-buffer> will
receive the current line (row) location while the second receives the
current column location.

The returned location data will be in binary form, and will be based
upon starting values of 0, meaning that if the cursor is located at
line 15, column 12 at the time this routine is called, a value of
(14,11) will be returned.

The following is a typical <cursor-locn-buffer> definition:

     01  CURSOR-LOCN-BUFFER.
         05 CURSOR-LINE          USAGE BINARY-CHAR.
         05 CURSOR-COLUMN        USAGE BINARY-CHAR.

Values of 1 (Line) and 1 (column) will be returned if GNU COBOL was not
generated to include screen I/O.

8.3.29. CBL_GET_CURRENT_DIR
---------------------------

             CBL_GET_CURRENT_DIR Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_GET_CURRENT_DIR" USING BY VALUE 0,
 ~~~~                       ~~~~~    ~~~~~
                                  BY VALUE length,
                                     ~~~~~
                                  BY REFERENCE buffer
                                     ~~~~~~~~~

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

This retrieves the fully-qualified pathname of the current directory,
saving up to <length> characters of that name into the specified
<buffer>.

The first argument is unused, but must be specified.  It must be
specified "BY VALUE" (see CALL).

The <length> argument must be specified "BY VALUE".
 The <buffer>
argument must be specified "BY REFERENCE".

The value specified for the <length> argument (a numeric literal or
data item) should not exceed the actual length of the <buffer>
argument.

If the value specified for the <length> argument is LESS THAN the
actual length of the <buffer> argument, the current directory path will
be left-justified and space filled within the first <length> bytes of
<buffer> -- any bytes in <buffer> after that point will be unchanged.

If the routine is successful, a value of 0 will be returned to the
"RETURN-CODE" special register (see Special Registers).  If the
routine failed because of a problem with an argument (such as a
negative or 0 length), a value of 128 will result.  Finally, if the 1st
argument value is anything but zero, the routine will fail with a 129
value.

8.3.30. CBL_GET_SCR_SIZE
------------------------

               CBL_GET_SCR_SIZE Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_GET_SCR_SIZE" USING no-of-lines, no-of-cols
 ~~~~                    ~~~~~

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

Use this subroutine to retrieve the current console screen size.

When the system is running in a windowed environment, this will be the
sizing of the console window in which the program is executing.  When
the system is not running a windowing environment, the physical console
screen attributes will be returned.  In environments such as a Windows
console window, where the logical size of the window may far exceed
that of the physical console window, the size returned will be that of
the physical console window.  Two one-byte values will be returned --
the first will be the current number of lines (rows) while the second
will be the number of columns.

The returned size data will be in binary form.

The following are typical <no-of-lines> and <no-of-columns>
definitions:

     01  NO-OF-LINES             USAGE BINARY-CHAR.
     01  NO-OF-COLUMNS           USAGE BINARY-CHAR.

GNU COBOL run-time screen management must have been initialized prior
to CALLing this routine in order to receive meaningful values.  This
means that a "DISPLAY screen-data-item" statement (see DISPLAY screen-data-item)
or a "ACCEPT screen-data-item" statement (see
ACCEPT screen-data-item) must have been executed prior to executing
the "CALL" statement.

Zero values will be returned if the screen has not been initialized and
values of 24 (lines) and 80 (columns) will be returned if GNU COBOL was
not generated to include screen I/O.

8.3.31. CBL_IMP
---------------

                   CBL_IMP Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_IMP" USING item-1, item-2, BY VALUE byte-length
 ~~~~           ~~~~~                    ~~~~~

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

Old    Old    New      This subroutine performs a bit-by-bit logical
Arg 1  Arg 2  Arg 2    "implies" process between the left-most
Bit    Bit    Bit      8*<byte-length> corresponding bits of <item-1>
=====  =====  =====    and <item-2>, storing the resulting bit string
0      0      1        into <item-2>.  The truth table shown to the left
0      1      1        documents the IMP process.
1      0      0        The <item-1> argument may be an alphanumeric
1      1      1        literal or a data item and <item-2> must be a
                       data item.  The length of both <item-1> and
                       <item-2> must be at least 8*<byte-length>.

The <byte-length> argument may be a numeric literal or data item, and
must be specified using "BY VALUE" (see CALL).

Any bits in <item-2> after the 8*<byte-length> point will be
unaffected.

A result of zero will be passed back in the "RETURN-CODE" special
register (see Special Registers).

8.3.32. CBL_NIMP
----------------

                   CBL_NIMP Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_NIMP" USING item-1, item-2, BY VALUE byte-length
 ~~~~            ~~~~~                    ~~~~~

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

Old    Old    New      This subroutine performs the negation of a
Arg 1  Arg 2  Arg 2    bit-by-bit logical "implies" process between the
Bit    Bit    Bit      left-most 8*<byte-length> corresponding bits of
=====  =====  =====    <item-1> and <item-2>, storing the resulting bit
0      0      0        string into <item-2>.  The truth table shown to
0      1      0        the left documents the NIMP process.
1      0      1        The <item-1> argument may be an alphanumeric
1      1      0        literal or a data item and <item-2> must be a
                       data item.  The length of both <item-1> and
                       <item-2> must be at least 8*<byte-length>.

The <byte-length> argument may be a numeric literal or data item, and
must be specified using "BY VALUE" (see CALL).

Any bits in <item-2> after the 8*<byte-length> point will be
unaffected.

A result of zero will be passed back in the "RETURN-CODE" special
register (see Special Registers).

8.3.33. CBL_NOR
---------------

                   CBL_NOR Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_NOR" USING item-1, item-2, BY VALUE byte-length
 ~~~~           ~~~~~                    ~~~~~

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

Old    Old    New      This subroutine performs the negation of a
Arg 1  Arg 2  Arg 2    bit-by-bit logical "or" process between the
Bit    Bit    Bit      left-most 8*<byte-length> corresponding bits of
=====  =====  =====    <item-1> and <item-2>, storing the resulting bit
0      0      1        string into <item-2>.  The truth table shown to
0      1      0        the left documents the NOR process.
1      0      0        The <item-1> argument may be an alphanumeric
1      1      0        literal or a data item and <item-2> must be a
                       data item.  The length of both <item-1> and
                       <item-2> must be at least 8*<byte-length>.

The <byte-length> argument may be a numeric literal or data item, and
must be specified using "BY VALUE" (see CALL).

Any bits in <item-2> after the 8*<byte-length> point will be
unaffected.

A result of zero will be passed back in the "RETURN-CODE" special
register (see Special Registers).

8.3.34. CBL_NOT
---------------

                   CBL_NOT Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_NOT" USING item-1, BY VALUE byte-length
 ~~~~           ~~~~~            ~~~~~

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

This subroutine "flips" the left-most 8*<byte-length> bits of <item-1>,
changing 0 bits to 1s and 1s to 0s.  The changes are made directly im
<item-1>.

The <item-1> argument must be a data item.  The length of <item-1> must
be at least 8*<byte-length>.

The <byte-length> argument may be a numeric literal or data item, and
must be passed using "BY VALUE" (see CALL).

Any bits in <item-1> after the 8*<byte-length> point will be
unaffected.

A result of zero will be passed back in the "RETURN-CODE" special
register (see Special Registers).

8.3.35. CBL_OC_NANOSLEEP
------------------------

               CBL_OC_NANOSLEEP Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_OC_NANOSLEEP" USING nanoseconds-to-sleep
 ~~~~                    ~~~~~

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

This subroutine puts the program to sleep for the specified number of
nanoseconds.  The effective granularity of <nanoseconds-to-sleep>
values will depend upon the granularity of the system clock your
computer is using and the timing granularity of the operating system
that computer is running.  For example, I don^Zt expect you^Zll see any
difference whatsoever between values of 1, 100, 500 or 1000, but you
should see a difference between values such as 250000000 and
500000000.

The <nanoseconds-to-sleep> argument is a numeric literal or data item.

There are one BILLION nanoseconds in a second, so if you wanted to put
the program to sleep for 1/4 second you'd use a <nanoseconds-to-sleep>
value of 250000000.

8.3.36. CBL_OPEN_FILE
---------------------

                CBL_OPEN_FILE Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_OPEN_FILE" USING file-path, access-mode, 0, 0, handle
 ~~~~                 ~~~~~

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

This routine opens an existing file for use as a byte-stream file
usable by CBL_WRITE_FILE or CBL_READ_FILE.

The <file-path> argument  is an alphanumeric literal or data-item.

The <access-mode> argument is a numeric literal or data item with a PIC
X USAGE COMP-X (or USAGE BINARY-CHAR) definition; it specifies how you
wish to use the file, as follows:

     1 = input (read-only)
     2 = output (write-only)
     3 = input and/or output

The third and fourth arguments would specify a locking mode and device
specification, respectively, but they're not implemented in GNU COBOL
(currently, at least) -- just specify each as 0.

The final argument (<handle>) is a "PIC X(4) USAGE COMP-X" item that
will receive the handle to the file.  That handle is used on all other
byte-stream functions to reference this specific file.

A "RETURN-CODE" special register (see Special Registers) value of
-1 indicates an invalid argument, while a value of 0 indicates success.
A value of 35 means the file does not exist.

8.3.37. CBL_OR
--------------

                    CBL_OR Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_OR" USING item-1, item-2, BY VALUE byte-length
 ~~~~          ~~~~~                    ~~~~~

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

Old    Old    New      This subroutine performs a bit-by-bit logical
Arg 1  Arg 2  Arg 2    "or" process between the left-most
Bit    Bit    Bit      8*<byte-length> corresponding bits of <item-1>
=====  =====  =====    and <item-2>, storing the resulting bit string
0      0      0        into <item-2>.  The truth table shown to the left
0      1      1        documents the OR process.
1      0      1        The <item-1> argument may be an alphanumeric
1      1      1        literal or a data item and <item-2> must be a
                       data item.  The length of both <item-1> and
                       <item-2> must be at least 8*<byte-length>.

The <byte-length> argument may be a numeric literal or data item, and
must be specified using "BY VALUE" (see CALL).

Any bits in <item-2> after the 8*<byte-length> point will be
unaffected.

A result of zero will be passed back in the "RETURN-CODE" special
register (see Special Registers).

8.3.38. CBL_READ_FILE
---------------------

                CBL_READ_FILE Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_READ_FILE" USING handle, offset, nbytes, flag, buffer
 ~~~~                 ~~~~~

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

This routine reads <nbytes> of data starting at byte number <offset>
from the byte-stream file defined by <handle> into the specified
<buffer>.

The <handle> argument ("PIC X(4) USAGE COMP-X") must have been
populated by a prior call to "CBL_OPEN_FILE" built-in system subroutine
(see CBL_OPEN_FILE).

The <offset> argument ("PIC X(8) USAGE COMP-X") defines the location in
the file of the first byte to be read.  The first byte of a file is
byte offset 0.

The <nbytes> argument ("PIC X(4) USAGE COMP-X") specifies how many
bytes (maximum) will be read.
 If the <flag> argument is specified as
128, the size of the file (in bytes) will be returned into the file
offset argument (argument 2) upon completion.  Not all operating
system/GNU COBOL environments may be able to retrieve file sizes ^Z in
such cases, a value of zero will be returned.  The only other valid
value for flags is 0.  This argument may be specified either as a
numeric literal or as a "PIC X USAGE COMP-X" data item.

Upon completion, the "RETURN-CODE" special register (see Special Registers)
will be set to 0 if the read was successful or to 10 if an
"end-of-file" condition occurred.  If a value of -1 is returned, a
problem was identified with the subroutine arguments.

8.3.39. CBL_RENAME_FILE
-----------------------

               CBL_RENAME_FILE Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_RENAME_FILE" USING old-file-path, new-file-path
 ~~~~                   ~~~~~

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

You may use this subroutine to rename a file.

The file specified by <old-file-path> will be "renamed" to the name
specified as <new-file-path>.  Each argument may be an alphanumeric
literal or data item.

Despite what the name of this routine might make you believe, this
routine is more than just a simple "rename" -- it will actually move
the file supplied as the 1st argument to the file specified as the 2nd
argument.  Think of it as a two-step sequence, first copying the
<old-file-path> file to the <new-file-path> file and then a second step
where the <old-file-path> is deleted.

If the attempt to move the file fails (for example, it doesn't exist),
the "RETURN-CODE" special register (see Special Registers) will be
set to 128; on successful completion it will be set to 0.

8.3.40. CBL_TOLOWER
-------------------

                 CBL_TOLOWER Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_TOLOWER" USING data-item, BY VALUE convert-length
 ~~~~               ~~~~~               ~~~~~

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

This routine will convert the first <convert-length> (a numeric literal
or data item) characters of <data-item> (an alpha-numeric identifier)
to lower-case.

The <convert-length> argument must be specified "BY VALUE" (see
CALL).  It specifies how many (leading) characters in data-item will
be converted -- any characters after that will remain unchanged.

If <convert-length> is negative or zero, no conversion will be
performed.

8.3.41. CBL_TOUPPER
-------------------

                 CBL_TOUPPER Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_TOUPPER" USING data-item, BY VALUE convert-length
 ~~~~               ~~~~~               ~~~~~

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

This routine will convert the first <convert-length> (a numeric literal
or data item) characters of <data-item> (an alpha-numeric identifier)
to upper-case.

The <convert-length> argument must be specified "BY VALUE" (see
CALL).  It specifies how many (leading) characters in data-item will
be converted -- any characters after that will remain unchanged.

If <convert-length> is negative or zero, no conversion will be
performed.

8.3.42. CBL_WRITE_FILE
----------------------

                CBL_WRITE_FILE Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_WRITE_FILE" USING handle, offset, nbytes, 0, buffer
 ~~~~                  ~~~~~

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

This routine writes <nbytes> of data from the specified <buffer> to the
byte-stream file defined by <handle> starting at byte number <offset>
within the file.

The <handle> argument ("PIC X(4) USAGE COMP-X") must have been
populated by a prior call to CBL_OPEN_FILE.
 The offset argument ("PIC
X(4) USAGE COMP-X") defines the location in the file of the first byte
to be written to.  The first byte of a file is byte offset 0.

The <nbytes> argument ("PIC X(4) USAGE COMP-X") specifies how many
bytes (maximum) will be written.

Currently, the only allowable value for the flags argument is 0.  This
argument may be specified either as a numeric literal or as a "PIC X(1)
USAGE COMP-X" data item.

Upon completion, the "RETURN-CODE" special register (see Special Registers)
will be set to 0 if the write was successful or to 30 if
an I/O error condition occurred.  If a value of -1 is returned, a
problem was identified with the subroutine arguments.

8.3.43. CBL_XOR
---------------

                   CBL_XOR Built-In Subroutine Syntax
=======================================================================

 CALL "CBL_XOR" USING item-1, item-2, BY VALUE byte-length
 ~~~~           ~~~~~                    ~~~~~

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

Old    Old    New      This subroutine performs a bit-by-bit logical
Arg 1  Arg 2  Arg 2    "exclusive or" process between the left-most
Bit    Bit    Bit      8*<byte-length> corresponding bits of <item-1>
=====  =====  =====    and <item-2>, storing the resulting bit string
0      0      0        into <item-2>.  The truth table shown to the left
0      1      1        documents the XOR process.
1      0      1        The <item-1> argument may be an alphanumeric
1      1      0        literal or a data item and <item-2> must be a
                       data item.  The length of both <item-1> and
                       <item-2> must be at least 8*<byte-length>.

The <byte-length> argument may be a numeric literal or data item, and
must be specified using "BY VALUE" (see CALL).

Any bits in <item-2> after the 8*<byte-length> point will be
unaffected.

A result of zero will be passed back in the "RETURN-CODE" special
register (see Special Registers).

8.3.44. SYSTEM
--------------

                    SYSTEM Built-In Subroutine Syntax
=======================================================================

 CALL "SYSTEM" USING command
 ~~~~          ~~~~~

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

This subroutine submits the specified <command> (an alphanumeric
literal or data item) to a command shell for execution as if it were
typed into a console/terminal window.

A shell will be opened subordinate to the GNU COBOL program issuing the
call to "SYSTEM".

Output from the command (if any) will appear in the command window in
which the GNU COBOL program was executed.

On a Unix system, the shell environment will be established using the
default shell program.  This is also true when using a GNU COBOL build
created with and for OSX or the Cygwin Unix emulator.

With native Windows Windows/MinGW builds, the shell environment will be
the Windows console window command processor (usually "cmd.exe")
appropriate for the version of Windows you're using.

To trap output from the executed command and process it within the GNU
COBOL program, use a pipe (>) to send the command output to a temporary
file which you read from within the program once control returns.

8.3.45. X"91"
-------------

                    X"91" Built-In Subroutine Syntax
=======================================================================

 CALL X"91" USING return-code, function-code, binary-variable-arg
 ~~~~       ~~~~~

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

The original Micro Focus version of this routine is capable of
providing a wide variety of functions.  GNU COBOL supports just three
of them:

   * Turning runtime switches (SWITCH-1, ... , SWITCH-8) on.

   * Turning runtime switches (SWITCH-1, ... , SWITCH-8) off.

   * Retrieving the number of arguments passed to a subroutine.

The <return-code> argument must be a one-byte binary numeric data item
("USAGE BINARY-CHAR" is recommended).  It will receive a value of 0 if
the operation was successful, 1 otherwise.

The <function-code> argument must be either a numeric literal or a
one-byte binary numeric data item ("USAGE BINARY-CHAR" is
recommended).

The third argument -- <variable-arg> -- is defined differently
depending upon the <function-code> value, as follows:

11

     Sets and/or clears all eight of the COBOL switches (SWITCH-1
     through SWITCH-8).  See SPECIAL-NAMES, for an explanation of
     those switches.

     The <variable-arg> argument should be an "OCCURS 8 TIMES" table of
     "USAGE BINARY-CHAR".

     Each occurrence that is set to a value of zero prior to the "CALL
     X"91"" will cause the corresponding switch to be cleared.  Each
     occurrence set to 1 prior to the "CALL X"91"" will cause the
     corresponding switch to be set.

     Values other than 0 or 1 will be ignored.

12

     Reads all eight of the COBOL switches (SWITCH-1 through SWITCH-8)

     The <variable-arg> argument should be an "OCCURS 8 TIMES" table of
     "USAGE BINARY-CHAR".

     Each of the 1st eight occurrences of the array will be set to
     either 0 or 1 -- 1 if the corresponding switch is set, 0
     otherwise.

16

     Retrieves the number of arguments passed to the program executing
     the CALL X"91", saving that number into the <variable-arg>
     argument.  That should be a binary numeric data item ("USAGE
     BINARY-CHAR" is recommended).

8.3.46. X"E4"
-------------

                    X"E4" Built-In Subroutine Syntax
=======================================================================

 CALL X"E4"
 ~~~~

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

Use X"E4" to clear the screen.  There are no arguments and no returned
value.

8.3.47. X"E5"
-------------

                    X"E5" Built-In Subroutine Syntax
=======================================================================

 CALL X"E5"
 ~~~~

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

The X"E5" routine will sound the PC "bell".  There are no arguments and
no returned value.

8.3.48. X"F4"
-------------

                    X"F4" Built-In Subroutine Syntax
=======================================================================

 CALL X"F4" USING byte, table
 ~~~~       ~~~~~

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

This routine packs the low-order (rightmost) bit from each of the eight
1-byte items in <table> into the corresponding bit positions of the
single-byte data item <byte>.

The <byte> data item need be only a single byte in size.  If it is
longer, the excess will be unaffected by this subroutine.

The <table> data item must be at least 8 bytes long.  If it is longer,
the excess will be ignored by this subroutine.

Typically, table is defined similarly to the following:

     01  Table-Arg.
         05 Each-Byte OCCURS 8 TIMES USAGE BINARY-CHAR.

8.3.49. X"F5"
-------------

                    X"F5" Built-In Subroutine Syntax
=======================================================================

 CALL X"F5" USING byte, table
 ~~~~       ~~~~~

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

This routine unpacks each bit of the single-byte data item <byte> into
the low-order (rightmost) bit of each of the corresponding eight 1-byte
items in <table>.  The other seven bit positions of each of the first
eight entries in <table> will be set to zero.

The <byte> data item need be only a single byte in size.  If it is
longer, the excess will be unaffected by this subroutine.

The <table> data item must be at least 8 bytes long.  If it is longer,
the excess will be ignored by this subroutine.

Typically, table is defined similarly to the following:

     01  Table-Arg.
         05 Each-Byte OCCURS 8 TIMES USAGE BINARY-CHAR.

8.4. Binary Truncation
======================

By default, the GNU COBOL compiler will truncate binary data items to
the precision indicated by their "PICTURE" (see PICTURE) clause, if
they have one.  For example, the following data item will have 2 bytes
of storage allocated for it:

                  01  Comp-5-Item   PIC 9(3) COMP-5.

Because of truncation, even though this field has enough bits allocated
(16) to store values from 0 to 65535, it will be limited to values of 0
to 999 because of its "PICTURE".

Or is it?

Take a look at the small demo program shown here.  This program will
perform three different types of operations against a binary field,
displaying the results of each:

     IDENTIFICATION DIVISION.
     PROGRAM-ID. DEMOTRUNC.
     ENVIRONMENT DIVISION.
     DATA DIVISION.
     WORKING-STORAGE SECTION.
     01  Bin-Item-1  PIC 9(3) COMP-5 VALUE 32760.
     01  Disp-Item-1 PIC 9(6).
     PROCEDURE DIVISION.
     000-Main.
         MOVE Bin-Item-1 TO Disp-Item-1
         DISPLAY 'Bin-Item-1='  Bin-Item-1 ' Disp-Item-1=' Disp-Item-1
         ADD 5 TO Bin-Item-1
         MOVE Bin-Item-1 TO Disp-Item-1
         DISPLAY 'Bin-Item-1='  Bin-Item-1 ' Disp-Item-1=' Disp-Item-1
         MOVE 32767 TO Bin-Item-1
         MOVE Bin-Item-1 TO Disp-Item-1
         DISPLAY 'Bin-Item-1='  Bin-Item-1 ' Disp-Item-1=' Disp-Item-1
         STOP RUN
         .

Here are the results when the program is compiled (with truncation
in-effect by default) and executed:

     Bin-Item-1=760 Disp-Item-1=032760
     Bin-Item-1=765 Disp-Item-1=032765
     Bin-Item-1=767 Disp-Item-1=032767

You can see that truncation affected the "DISPLAY" statements but
appears to have had no impact whatsoever on the "MOVE" and "ADD"
statements.  This is the hidden secret about truncation in GNU COBOL:
it doesn't really truncate the internally-stored values -- it just
truncates the "DISPLAY" of them!

If that same program is recompiled without truncation (by adding the
"-fnotrunc" switch switch to the 'cobc' command), the results are as
follows:

     Bin-Item-1=32760 Disp-Item-1=032760
     Bin-Item-1=32765 Disp-Item-1=032765
     Bin-Item-1=32767 Disp-Item-1=032767

If this was all there was to the binary truncation issue it wouldn't be
worth a section in this document.  The fact is, however, that binary
truncation has a significant effect on the performance of GNU COBOL
programs.  When binary truncation is in effect, arithmetic operations
performed against all types of numeric data items (even "USAGE
DISPLAY") are slowed down.

Before continuing, it's worth making the point that we're NOT talking
about astronomical performance degradations here.  Today's computers
are FAST, and a user sitting at the keyboard, running a GNU COBOL
program is unlikely to notice.  BUT ... if you have a GNU COBOL program
that has to process large amounts of data, performing some significant
"number crunching" against that data as it goes, the impact of
truncation could become noticeable.

The following program compares the performance of performing arithmetic
operations (in a totally non-scientific, non-rigorous way) against data
items with a "USAGE" (see USAGE) of "DISPLAY", "COMP", "COMP-5" and
"BINARY-LONG".  It was actually my intent when I first wrote the
program to merely demonstrate the relative performance differences
between different types of numeric data storage, and it certainly met
that objective.

     IDENTIFICATION DIVISION.
     PROGRAM-ID. DEMOMATH.
     DATA DIVISION.
     WORKING-STORAGE SECTION.
     01  Begin-Time.
         05 BT-HH                    PIC 9(2).
         05 BT-MM                    PIC 9(2).
         05 BT-SS                    PIC 9(2).
         05 BT-HU                    PIC 9(2).
     01  Binary-Item         BINARY-LONG SIGNED VALUE 0.
     01  Comp-Item           COMP    PIC S9(9)  VALUE 0.
     01  Comp-5-Item         COMP-5  PIC S9(9)  VALUE 0.
     01  Display-Item        DISPLAY PIC S9(9)  VALUE 0.
     01  End-Time.
         05 ET-HH                    PIC 9(2).
         05 ET-MM                    PIC 9(2).
         05 ET-SS                    PIC 9(2).
         05 ET-HU                    PIC 9(2).
     78  Repeat-Count                VALUE 10000000.
     01  Time-Diff                   PIC ZZ9.99.
     PROCEDURE DIVISION.
     010-Test-Usage-DISPLAY.
         ACCEPT  Begin-Time FROM TIME
         PERFORM Repeat-Count TIMES
             ADD 7 TO Display-Item
         END-PERFORM
         PERFORM 100-Determine-Time-Diff
         DISPLAY 'USAGE DISPLAY: ' Time-Diff ' SECONDS'
         .
     020-Test-Usage-COMP.
         ACCEPT Begin-Time FROM TIME
         PERFORM Repeat-Count TIMES
             ADD 7 TO Comp-Item
         END-PERFORM
         PERFORM 100-Determine-Time-Diff
         DISPLAY 'USAGE COMP:    ' Time-Diff ' SECONDS'
         .
     030-Test-Usage-COMP-5.
         ACCEPT Begin-Time FROM TIME
         PERFORM Repeat-Count TIMES
             ADD 7 TO Comp-5-Item
         END-PERFORM
         PERFORM 100-Determine-Time-Diff
         DISPLAY 'USAGE COMP-5:  ' Time-Diff ' SECONDS'
         .
     040-Test-Usage-BINARY.
         ACCEPT Begin-Time FROM TIME
         PERFORM Repeat-Count TIMES
             ADD 7 TO Binary-Item
         END-PERFORM
         PERFORM 100-Determine-Time-Diff
         DISPLAY 'USAGE BINARY:  ' Time-Diff ' SECONDS'
         .
     099-Done.
         STOP RUN
         .
     100-Determine-Time-Diff.
         ACCEPT End-Time FROM TIME
         COMPUTE Time-Diff =
           ( (ET-HH * 360000 + ET-MM * 6000 + ET-SS * 100 + ET-HU)
           - (BT-HH * 360000 + BT-MM * 6000 + BT-SS * 100 + BT-HU) )
           / 100
         .

Each data item has 7 added to it ten million times.

The time (to one-one-hundredth of a second) will be retrieved before
and after each test and the difference between the two is displayed.
This is why the computations were done so many times -- it was to make
sure the timing was "measurable" with only a 1/100 second "stopwatch".

I also ran the tests multiple times, just to make sure I had consistent
results (I did).  Like I mentioned earlier, this is not a rigorous,
scientific benchmark of numeric performance; it's just a
quick-and-dirty comparison.

Here are the results:

     USAGE DISPLAY: 3.83 SECONDS
     USAGE COMP:    1.23 SECONDS
     USAGE COMP-5:  0.04 SECONDS
     USAGE BINARY:  0.04 SECONDS

The results I saw here were consistent with those that would have been
obtained from most of the COBOL implementations I have ever worked with
-- "USAGE COMP" has a significant performance advantage over "USAGE
DISPLAY", "USAGE COMP-5" has a significant performance advantage over
"USAGE COMP" and "USAGE BINARY-LONG" (and presumably the other
"BINARY-xxx" usages as well) perform identically, within the
measurement tolerances of the test, as "COMP-5".  This was expected
since "COMP-5" and "BINARY-xxx" both allocate data the same way.

Imagine my surprise, however, when I discovered that the use of
"-fnotrunc" switch also made a significant difference:

     USAGE DISPLAY: 3.85 SECONDS
     USAGE COMP:    0.09 SECONDS
     USAGE COMP-5:  0.04 SECONDS
     USAGE BINARY:  0.04 SECONDS

As you can see, there was a huge drop in "USAGE COMP" timings by
turning off truncation.  As a result, I see absolutely no reason
whatsoever why the "-fnotrunc" switch option shouldn't be used on all
GNU COBOL compilations.

If you want to squeeze every last bit of performance out of your GNU
COBOL programs, don't forget to investigate the "-O" switch, "-O2"
switch and the "-Os" switch, all of which influence the optimization of
compiled code.  Actually run programs using various optimization
switches (or not) and compare execution times against those of
unoptimized compiled versions of your programs.  Don't just compare the
generated C code because sometimes the differences can't be "seen" at
the C source-code level.

9.1. Subprogram Types
=====================

Simply stated, a 'Subprogram' is a program that is invoked by another
program; the subprogram performs whatever its designed operations are
and -- when complete -- typically returns control back to the program
that invoked it.  There are two different types of subprograms
supported by GNU COBOL, subroutines and user-defined functions.  The
distinction between these two subprogram types lies in the manner in
which they are executed.

When program "A" invokes subprogram "B" as a 'Subroutine', it does so
using a special statement dedicated to that function (the "CALL"
statement (see CALL), just as if "B" were one of the built-in
system subroutines.

When program "A" invokes program "B" as a 'User-Defined Function', it
does so in a manner identical to how "B" would have been invoked had it
been one of the many built-in intrinsic functions.

In either instance, program "A" is referred to as the 'Calling Program' while
program "B" is known as the 'Called Program'.  GNU COBOL programs may
be a calling program, a called program or both.

A program written in the C programming language may serve as either the
calling or called program too.  A called program may act as a calling
program to another called program.  When a calling program does not
serve as a called program to any program, that calling program is known
as a 'Main Program'.

Both subroutines and user-defined functions may return a value.  The
value they return must be an integer in the range -2147483648 to
+2147483647.  This value will be available in the "RETURN-CODE" special
register (see Special Registers) and also as the value of the data
item specified on the "RETURNING" (see CALL) clause of a
subroutine's CALL.

9.2. Independent vs Contained vs Nested Subprograms
===================================================

Subprograms (either subroutines or user-defined functions) can be
implemented in three different ways.

'Independent Subprograms'

     These are subprograms that are coded as the only COBOL program in
     their Compilation Unit (see Compilation Unit).

'Contained Subprograms'

     These are subprograms which occur in the same Compilation Unit as
     a main program and/or other subprograms.  Each contained
     subprogram is separated from the next via an "END PROGRAM" marker
     line.  As an example...

          IDENTIFICATION DIVISION.
          PROGRAM-ID. SUB1.
          ...
          END PROGRAM SUB1.
          IDENTIFICATION DIVISION.
          PROGRAM-ID. SUB2.
          ...
          END PROGRAM SUB2.

     Program source code may be concatenated as shown here, provided an
     "END PROGRAM" marker naming the "PROGRAM-ID" of the just-completed
     program is used to separate one program from another.

     There's no reason that user-defined functions cannot be included
     too -- they'll just have "FUNCTION-ID"s and will be ended by "END
     FUNCTION" markers.

     The last program in any GNU COBOL source file need not have an
     "END" marker.

     When multiple programs occur in a source file, it is assumed that
     the programs are related to one another in that they will be
     CALLed or executed as functions from the others.

'Nested Subprograms'

     It is also possible to create source files where GNU COBOL
     programs are nested inside each other.  Take for example these
     four GNU COBOL programs:

          IDENTIFICATION DIVISION.
          PROGRAM-ID. PROG1.
          ...
          IDENTIFICATION DIVISION.
          PROGRAM-ID. PROG2.
          ...
          IDENTIFICATION DIVISION.
          PROGRAM-ID. PROG3.
          ...
          END PROGRAM PROG3.
          END PROGRAM PROG2.
          IDENTIFICATION DIVISION.
          PROGRAM-ID. PROG4.
          ...
          END PROGRAM PROG4.
          END PROGRAM PROG1.

     Here we see that PROG2 is nested inside of PROG1 because there is
     no "END PROGRAM" marker separating them.  This means that data
     items or files defined within PROG1 can be used within PROG2
     simply by attaching the "GLOBAL" (see GLOBAL) attribute to
     them back in PROG1 when they are defined.

     Similarly, since there is no "END PROGRAM" marker separating PROG3
     from PROG2, it is possible for PROG3 to access "GLOBAL" files and
     data items defined within PROG2.  Since PROG2 is nested within
     PROG1, any "GLOBAL" resources defined within PROG1 will be
     available to PROG3 as well.

     The two "END PROGRAM" markers for PROG3 and PROG2 (note their
     sequence) mean that PROG4 is nested within PROG1 only.  It will
     not have access to any "GLOBAL" resources defined within either
     PROG2 or PROG3.

     The "END PROGRAM PROG1." marker, since it is the last line in the
     source file, is entirely optional.

9.3. Alternate Entry Points
===========================

Any subroutine may have multiple entry-points defined within it.  This
means the subroutine could be called either via a "CALL '<program-id>'"
or a "CALL '<entry-point>'" statement.  There may be any number of
alternate entry-points defined within a subroutine.

Alternate entry-points provide multiple ways in which the same
subroutine may be called; presumably, each entry-point will provide
some different functionality to the calling program.  For example, if
you wished to write a subroutine that manipulates "student" records in
a database, you might have the primary entry-point name retrieve a
student record from the database, while the alternate entry points
"Add-Student", "Update-Student" and "Delete-Student" could provide the
alternate functions implied by their entry-point names.

The alternative to using multiple entry points in your subroutine, by
the way, would be to include an additional argument to the primary (and
only) entry point of the subroutine; this new argument might be named
"STUDENT-FUNCTION" and might have values of "FETCH", "ADD", "UPDATE" or
"DELETE".

The primary entry-point for any subroutine is always the first
executable statement following any "DECLARATIVES" (see
DECLARATIVES) in the procedure division.  The name of that
entry-point (the name that will be called) is the subroutine's
"PROGRAM-ID" (see IDENTIFICATION DIVISION).

An alternate entry point is added to a subroutine using the "ENTRY"
statement (see ENTRY).

When an alternate entry-point is called, execution within the
subroutine will begin at the first executable statement following the
"ENTRY" statement.

9.4. Dynamic vs Static Subprograms
==================================

Any subprogram may be either statically or dynamically loaded into
memory.

A 'Static Subprogram' is one which was in the same Compilation Unit
(see Compilation Unit) as the other program(s) which call it,
therefore meaning that it's executable object code is part of the same
executable file as it's calling program.  The static subprogram was
therefore loaded into memory as part of and at the same time as the
calling program.

A 'Dynamic Subprogram' is one whose executable object code exists as an
executable file separate from that containing the calling program;
these two programs were therefore each compiled in their own separate
Compilation Group (see Compilation Group).  Dynamic subprograms are
located and loaded into memory the first time they are executed.
Dynamic subprograms may be unloaded from memory via the "CANCEL"
statement (see CANCEL), if desired.

GNU COBOL subprograms may be created as either static or dynamic
subprograms, as desired by the programmer.

To demonstrate, assume that a GNU COBOL Main Program (whose code
resides in the file "M.cbl") will be calling three subprograms, named
"A", "B" and "C" (these are the "PROGRAM-ID"s of the three subprograms,
and their source code may be found in the files "A.cbl", "B.cbl" and
"C.cbl", respectively.

Here is how these four programs would be compiled if the three
subprograms are to be static:

                   "cobc -x M.cbl A.cbl B.cbl C.cbl"

This command informs the compiler (cobc) that four programs are to be
compiled (the first named on the command must always be the main
program), and a single executable file is to be created (due to the
"-x" switch).

Here is how the main program and the three subprograms could be
compiled if the three subprograms are to be dynamic:

                            "cobc -x M.cbl"

                      "cobc -m A.cbl B.cbl C.cbl"

These commands will create an executable file for the main program
("-x" switch) and three separate dynamically-loadable libraries ("-m"
switch), one for each of the three subprograms.  Had we wished, we
could have created a single dynamically-loadable library containing all
three subprograms by adding the "-b" switch to their compilation:

                    "cobc -m -b A.cbl B.cbl C.cbl"

Dynamically-loadable libraries are also known by the term
dynamically-loadable modules -- the two terms are synonymous.

Here are the rules about GNU COBOL dynamically-loadable modules:

  1. There may be multiple GNU COBOL subprograms contained within a
     single dynamically-loadable library if the "-b" switch is used in
     addition to "-m".  If not, each subprogram will be compiled to a
     separate dynamically-loadable library.

  2. Dynamically-loadable modules will be named "xxxxxxxx.dll" on a
     Windows system, "xxxxxxxx.so" on a Unix system or "xxxxxxxx.dylib"
     on an OSX system, where "xxxxxxxx" exactly matches, including the
     usage of upper- and lower-case letters, the primary entry-point
     name ("PROGRAM-ID" or "FUNCTION-ID") or an alternate entry point
     name defined via the "ENTRY" statement (see ENTRY) of any one
     of the GNU COBOL programs included in that module.

  3. The first time any of the GNU COBOL subprograms in a
     dynamically-loadable module are invoked, the entry-point
     referenced must be the one for which the ".dll", ".so" or ".dylib"
     file is named.

  4. When a dynamically-loadable module needs to be loaded (because it
     is not already in memory from a previous subprogram execution),
     the dynamically-loadable library will be sought in the same
     directory from which the main program was loaded.  If it cannot be
     found there, each directory named in the "PATH" run-time
     environment variable (see Run Time Environment Variables) will
     be searched.  If it was not located in any of those directories,
     the library specified by the "COB_LIBRARY_PATH" run-time
     environment variable will be searched.  Finally, if it still
     cannot be located, execution will be terminated with an error
     message ("libcob: Cannot find module 'xxxxxxxx'").

  5. Once the dynamically-loadable module has been successfully loaded,
     any of the entry-points contained within it are now available for
     reference.

  6. Dynamically-loadable modules may be removed from memory via the
     "CANCEL" statement (see CANCEL).

  7. Once a dynamically-loadable module is actually loaded into memory,
     even if it is subsequently unloaded (via the "CANCEL" statement),
     it's list of entry-points remain available to the GNU COBOL
     run-time library and subsequent re-executions of any of those
     entry points will be able to bypass the search (rule #4) as well
     as the "first-execution rule" (rule #3).

Consult the documentation on the "COB_PRE_LOAD" run-time environment
variable, "COB_PHYSICAL_CANCEL" run-time environment variable and "COB_LOAD_CASE"
run-time environment variable run-time environment variables (see Run Time Environment Variables)
for additional options when using
dynamically-loadable modules.

9.5. Subprogram Execution Flow
==============================

When a subprogram is invoked, the flow of execution will differ
slightly depending on whether the subprogram is a subroutine or a
user-defined function.

9.5.1. Subroutine Execution Flow
--------------------------------

When a subroutine is "CALL"ed:

  1. The calling program issues a statement of the form "CALL
     '<entry-point>' USING ..." to transfer control to the subroutine.

  2. The executable for the called program will be located and loaded
     into memory:

       A. If it is a static subroutine, it will already be part of the
          executable program issuing the "CALL" (see CALL).

       B. If it is a dynamic subroutine, the GNU COBOL run-time system
          will check to see if a dynamically-loadable module containing
          the subprogram's entry point was already located.  If it was,
          no further "location" activity is needed.  If not, the
          dynamically-loadable module will be located (see Locating Dynamically-Loadable Modules).

       C. Once the module has been located (if location was needed), it
          will be loaded into memory (if not already loaded).

  3. Execution of the calling program is suspended and control will
     transfer to the called program, as follows:

       A. If the "PROGRAM-ID" (see IDENTIFICATION DIVISION) clause
          of the subprogram included the "INITIAL" clause, the program
          will be reinitialized back to its compile-time state.  This
          will happen regardless of the "INITIAL" clause the first time
          the subprogram is executed.

       B. Local-storage, if any, will be allocated and initialized.

       C. Execution will begin at the first executable statement
          following the subprograms entry-point.  The entry point will
          be either the first executable statement following any
          "DECLARATIVES" (see DECLARATIVES) that might be present
          (if the subprogram was invoked using its primary entry-point
          name) or the first executable statement following the "ENTRY"
          statement (see ENTRY) naming the entry-point specified on
          the "CALL" if the subprogram was invoked using an alternate
          entry point.

  4. The flow of execution will then progress through the coding of the
     subprogram as it would with any other program.

  5. If the subprogram issues a "STOP" statement (see STOP) with
     the "RUN" option, program execution ceases and control returns to
     the operating system or whatever execution shell invoked the main
     program.

  6. If the subprogram wishes to return control back to the calling
     program, it will do so using either the "GOBACK" statement (see
     GOBACK) or the "EXIT PROGRAM" statement (see EXIT).  At this
     time:

       A. If the subprograms procedure division header or "ENTRY"
          statement included a "RETURNING", the value of the data item
          found on that clause is moved to the "RETURN-CODE" special
          register (see Special Registers); this behavior can be
          altered utilizing the "CALL-CONVENTION" (see
          SPECIAL-NAMES) feature to leave "RETURN-CODE" unchanged.

       B. Local-storage, if any, is de-allocated.

       C. If the calling program included a "RETURNING" clause on the
          "CALL" statement that invoked the subprogram, the value of
          the "RETURNING" data item in the subroutine is moved to that
          data item.  If there was no "RETURNING" specified in the
          subroutine, the value of the "RETURN-CODE" special register is
          moved to that data item.

       D. Execution will resume back in the calling program with the
          first executable statement following the "CALL" that invoked
          the subprogram.

9.5.2. User-Defined Function Execution Flow
-------------------------------------------

When a user-defined function is executed:

  1. The object code for the called program (the user-defined function)
     will be located, as follows:

       A. If it is a static user-defined function, it will already be
          part of the executable file containing the calling program.

       B. If it is a dynamic user-defined function, the GNU COBOL
          run-time system will check to see if a dynamically-loadable
          module containing the function's entry point was already
          located.  If it was, no further "location" activity is
          needed.  If not, the dynamically-loadable module will be
          located (see Locating Dynamically-Loadable Modules).

       C. Once the module has been located (if location was needed), it
          will be loaded into memory (if not already loaded).

  2. Execution of the calling program is suspended and control will
     transfer to the called program, as follows:

       A. Local-storage, if any, will be allocated and initialized.

       B. Execution will begin with the first executable statement in
          the procedure division following any "DECLARATIVES" (see
          DECLARATIVES) that might be present.

  3. The flow of execution will then progress through the coding of the
     function as it would with any other program.

  4. If the function issues a "STOP" statement (see STOP) with the
     "RUN" option, program execution ceases and control returns to the
     operating system or whatever execution shell invoked the main
     program.

  5. If the function wishes to return control back to the calling
     program, it will do so using either the "GOBACK" statement (see
     GOBACK) or the "EXIT FUNCTION" statement (see EXIT).  At
     this time:

       A. The value of the data item found on the user-defined
          functions "PROCEDURE DIVISION RETURNING" (see PROCEDURE DIVISION RETURNING)
          clause is moved to the "RETURN-CODE"
          special register (see Special Registers).

       B. Local-storage, if any, is de-allocated.

       C. Execution will resume back in the calling program at the
          point where the returned value of the function is needed.  At
          that point, the value in the "RETURN-CODE" special register will
          be used for the function's value.

9.6. Sharing Data Between Calling and Called Programs
=====================================================

9.5.1. Subprogram Arguments
---------------------------

9.6.1.1. Calling Program Considerations
.......................................

Data items defined in a calling program may be passed to either type of
called program (subroutine or user-defined function) as arguments.

Arguments must be described in both the calling and called programs,
and while they don't need to have the same names in both programs, they
should be described in an identical manner with regard to the following
characteristics:

   * "PICTURE" (see PICTURE) (including both type and length)

   * "SIGN" (see SIGN)

   * "SYNCRONIZED" (see SYNCRONIZED)

   * "USAGE" (see USAGE)

A subroutine may be passed a maximum of 36 arguments; if you build the
GNU COBOL software yourself from the distributed source, you CAN change
this value by altering the defined value of "COB_MAX_FIELD_PARAMS" in
the "common.h" header file.  There is no built-in GNU COBOL limit to
how many arguments a user-defined function may be passed.

Whether or not changes made to an argument within a subroutine will be
"visible" to the calling program depends on how the argument was
passed.  There are three ways in which arguments may be passed from a
calling program to a subroutine, as defined by the use of optional "BY"
clauses in the "CALL" (see CALL) statement's list of arguments.

As an example, the following statement passes three arguments to a
subroutine -- each argument is passed differently.

     CALL "subroutine" USING BY REFERENCE arg-1
                             BY CONTENT arg-2
                             BY VALUE arg-3
     END-CALL

The three ways arguments are passed are as follows.

"BY REFERENCE"

     When a subroutine argument is passed "BY REFERENCE", the
     subroutine is passed the address of the actual data item being
     passed as an argument.  The item may anything defined within the
     data division of the program.  If the subroutine modifies the
     contents of this argument, the calling program will "see" the
     results of that change when the subroutine returns control.  This
     is the default manner in which GNU COBOL passes arguments to a
     subroutine, should no "BY" clauses be included on the "CALL".

"BY CONTENT"

     When a subroutine is passed an argument "BY CONTENT", the
     subroutine is passed the address of a copy of the actual data
     being passed as an argument.  The item may anything defined within
     the data division of the program.  The copy is made each time the
     "CALL" statement is executed, immediately before the "CALL"
     actually takes place.  If the subroutine modifies the contents of
     this argument, it will be the copy that is modified, not the
     original data item; the calling program will therefore not "see"
     the results of that change when the subroutine returns control.

"BY VALUE"

     Passing a subroutine argument "BY VALUE" passes the actual value
     of the data being passed as an argument.  The item may be any
     elementary binary numeric item defined within the data division of
     the program.  If the subroutine modifies the contents of this
     argument, the calling program will not "see" the results of that
     change when the subroutine returns control.

The first two ways in which arguments may be passed ("BY REFERENCE" and
"BY CONTENT") are intended for use when a GNU COBOL program is being
called, while the first and third ("BY REFERENCE" and "BY VALUE") are
intended for use when a C program is being called.  You can use "BY
VALUE" arguments when calling GNU COBOL subroutines, but remember that
those arguments are limited to being a numeric binary data item.

Arguments to user-defined functions are always passed "BY REFERENCE".

9.6.1.2. Called Program Considerations
......................................

When coding a GNU COBOL subprogram (a subroutine or user-defined
function), all arguments to the subprogram must be defined in the
subprogram's linkage section.

These arguments must be explicitly included on the "PROCEDURE DIVISION
USING" (see PROCEDURE DIVISION USING) clause that lists the
arguments in the sequence in which they will be passed to the
subprogram.

These arguments described in the "PROCEDURE DIVISION USING" clause may
each be defined as either "BY REFERENCE", if the calling program is
passing them either "BY REFERENCE" or "BY CONTENT", or as "BY VALUE" if
they are being passed "BY VALUE".

By default, all arguments are assumed to be "BY REFERENCE" unless
explicitly stated otherwise on the procedure division header.

Arguments to a user-defined function are always to be specified as "BY
REFERENCE" (either explicitly or by not using any "BY").

If the subprogram returns a value, the data item in which the value is
returned must also be defined in the subprogram's linkage section, with
a "USAGE" (see USAGE) of "BINARY-LONG SIGNED", or it's equivalent.

9.6.2. GLOBAL Data Items
------------------------

Another way in which a data item may be shared between a calling
program ("A") and a called program ("B") is by defining the data item
in the calling program and attaching the "GLOBAL" (see GLOBAL)
clause to it so that it may be used within the called program.  In
order for this to work, program "B" (the one called by program "A")
must be a nested subprogram within program "A".

Here's a small example:

     IDENTIFICATION DIVISION.
     PROGRAM-ID. DemoGLOBAL.
     ENVIRONMENT DIVISION.
     DATA DIVISION.
     WORKING-STORAGE SECTION.
     01  Arg GLOBAL                     PIC X(10).
     PROCEDURE DIVISION.
     000-Main.
         MOVE ALL "X" TO Arg
         CALL "DemoSub" END-CALL
         DISPLAY "DemoGLOBAL: " Arg END-DISPLAY
         GOBACK
         .
     IDENTIFICATION DIVISION.
     PROGRAM-ID. DemoSub.
     PROCEDURE DIVISION.
     000-Main.
         MOVE ALL "*" TO Arg.
         GOBACK
         .
     END PROGRAM DemoSub.
     END PROGRAM DemoGLOBAL.

When the program runs, it produces the output:

     DemoGLOBAL: **********

9.6.3. EXTERNAL Data Items
--------------------------

The final way in which a data item may be shared between a calling
program ("A") and a called program ("B") is by defining the data item
(with the same name) in both programs and attaching the "EXTERNAL"
(see EXTERNAL) clause to it (again, in both programs).  This
approach works regardless of whether the called program is nested
within the calling program or not.  It also works even if the two
programs are compiled separately.

Here's a demonstration:

     IDENTIFICATION DIVISION.
     PROGRAM-ID. DemoEXTERNAL.
     ENVIRONMENT DIVISION.
     DATA DIVISION.
     WORKING-STORAGE SECTION.
     01  Arg EXTERNAL                PIC X(10).
     PROCEDURE DIVISION.
     000-Main.
         MOVE ALL "X" TO Arg
         CALL "DemoSub" END-CALL
         DISPLAY "DemoEXTERNAL: " Arg END-DISPLAY
         GOBACK
         .
     END PROGRAM DemoEXTERNAL.
     IDENTIFICATION DIVISION.
     PROGRAM-ID. DemoSub.
     DATA DIVISION.
     WORKING-STORAGE SECTION.
     01  Arg EXTERNAL                PIC X(10).
     PROCEDURE DIVISION.
     000-Main.
         MOVE ALL "*" TO Arg.
         GOBACK
         .
     END PROGRAM DemoSub.

When the program runs, it produces the output:

     DemoEXTERNAL: **********

9.7. Recursive Subprograms
==========================

A subroutine may "CALL" itself, either directly or indirectly from
another subroutine or user-defined function that it "CALL"s.  Any
subroutine that indulges in this sort of behavior (called recursion) is
called a 'Recursive Subprogram'.

Any GNU COBOL subroutine can be recursively invoked only if it is
defined to the GNU COBOL compiler as being a recursive subroutine.
This is accomplished by adding the "RECURSIVE" attribute to it's
"PROGRAM-ID" (see IDENTIFICATION DIVISION).

All User-defined functions are automatically capable of being executed
recursively.

Here is an example of a main program (DEMOFACT) that calls both a
subprogram (SUB) and a user-defined function (FUNC) to compute the
factorial value of a number.

     IDENTIFICATION DIVISION.
     PROGRAM-ID. DEMOFACT.
     ENVIRONMENT DIVISION.
     CONFIGURATION SECTION.
     REPOSITORY.
         FUNCTION RECURSIVEFUNC.
     DATA DIVISION.
     WORKING-STORAGE SECTION.
     01  Result    USAGE BINARY-LONG.
     01  Arg       USAGE BINARY-LONG.
     PROCEDURE DIVISION.
     000-Main.
         MOVE 6 TO Arg
         CALL "RECURSIVESUB"
             USING BY CONTENT Arg
             RETURNING Result
         DISPLAY Arg "! = "
                 Result
         DISPLAY Arg "! = "
                 RECURSIVEFUNC(Arg)
         GOBACK
         .
     END PROGRAM DEMOFACT.
     IDENTIFICATION DIVISION.
     PROGRAM-ID. SUB RECURSIVE.
     DATA DIVISION.
     WORKING-STORAGE SECTION.
     01  Result      USAGE BINARY-LONG.
     01  Next-Arg    USAGE BINARY-LONG.
     01  Next-Result USAGE BINARY-LONG.
     LINKAGE SECTION.
     01  Arg         USAGE BINARY-LONG.
     PROCEDURE DIVISION USING Arg
                    RETURNING Result.
     000-Main.
         DISPLAY "Entering SUB"
                 " Arg=" Arg
         IF Arg = 1
           MOVE 1 TO Result
           DISPLAY "Leaving SUB"
                   " Returning " Result
         ELSE
           SUBTRACT 1 FROM Arg
               GIVING Next-Arg
           CALL "SUB"
                USING BY CONTENT Next-Arg
                RETURNING Next-Result
           COMPUTE Result =
                   Arg * Next-Result
           DISPLAY "Leaving SUB"
                   " Returning "
                   Result "=" Arg "*"
                   Next-Result
         END-IF
         GOBACK
         .
     END PROGRAM SUB.
     IDENTIFICATION DIVISION.
     FUNCTION-ID. FUNC.
     ENVIRONMENT DIVISION.
     CONFIGURATION SECTION.
     REPOSITORY.
         FUNCTION RECURSIVEFUNC.
     DATA DIVISION.
     WORKING-STORAGE SECTION.
     LINKAGE SECTION.
     01  Arg     USAGE BINARY-LONG.
     01  Result  USAGE BINARY-LONG
                 SIGNED.
     PROCEDURE DIVISION USING Arg
                    RETURNING Result.
     000-Main.
         DISPLAY "Entering FUNC"
                 " Arg=" Arg
         IF Arg = 1
           MOVE 1 TO Result
         ELSE
           COMPUTE Result = Arg *
                   FUNC(Arg - 1)
         END-IF
         DISPLAY "Leaving FUNC"
                 " Returning " Result
         GOBACK
         .
     END FUNCTION FUNC.

When DEMOFACT is executed, the output shown below is generated.

     E:\Programs\Demos>demofact
     Entering RECURSIVESUB Arg=+0000000006
     Entering RECURSIVESUB Arg=+0000000005
     Entering RECURSIVESUB Arg=+0000000004
     Entering RECURSIVESUB Arg=+0000000003
     Entering RECURSIVESUB Arg=+0000000002
     Entering RECURSIVESUB Arg=+0000000001
     Leaving RECURSIVESUB Returning +0000000001
     Leaving RECURSIVESUB Returning +0000000002=+0000000002*+0000000001
     Leaving RECURSIVESUB Returning +0000000006=+0000000003*+0000000002
     Leaving RECURSIVESUB Returning +0000000024=+0000000004*+0000000006
     Leaving RECURSIVESUB Returning +0000000120=+0000000005*+0000000024
     Leaving RECURSIVESUB Returning +0000000720=+0000000006*+0000000120
     +0000000006! = +0000000720
     Entering RECURSIVEFUNC Arg=+0000000006
     Entering RECURSIVEFUNC Arg=+0000000005
     Entering RECURSIVEFUNC Arg=+0000000004
     Entering RECURSIVEFUNC Arg=+0000000003
     Entering RECURSIVEFUNC Arg=+0000000002
     Entering RECURSIVEFUNC Arg=+0000000001
     Leaving RECURSIVEFUNC Returning +0000000001
     Leaving RECURSIVEFUNC Returning +0000000002
     Leaving RECURSIVEFUNC Returning +0000000006
     Leaving RECURSIVEFUNC Returning +0000000024
     Leaving RECURSIVEFUNC Returning +0000000120
     Leaving RECURSIVEFUNC Returning +0000000720
     +0000000006! = +0000000720

9.8. Combining GNU COBOL and C Programs
=======================================

The upcoming sections deal the issues pertaining to calling C language
programs from GNU COBOL programs, and vice versa.  Two additional
sections provide samples illustrating specifics as to how those issues
are overcome in actual program code.

9.9.1. GNU COBOL Run-Time Library Requirements
----------------------------------------------

Like most other implementations of the COBOL language, GNU COBOL
utilizes a run-time library.  When the first program executed in a
given execution sequence is a GNU COBOL program, any run-time library
initialization will be performed by the compiled COBOL code in a manner
that is transparent to the C-language programmer.  If, however, a C
program is the first to execute, the burden of performing GNU COBOL
run-time library initialization falls upon the C program.  See C Main Programs Calling GNU COBOL Subprograms,
for an example of how to do
this.

9.9.2. String Allocation Differences Between GNU COBOL and C
------------------------------------------------------------

Both languages store strings as a fixed-length continuous sequence of
characters.

COBOL stores these character sequences up to a specific quantity limit
imposed by the "PICTURE" (see PICTURE) clause of the data item.
For example: "01  LastName   PIC X(15).".

There is never an issue of exactly what the length of a string
contained in a "USAGE DISPLAY" (see USAGE) data item is -- there
are always exactly how ever many characters as were allowed for by the
"PICTURE" clause.  In the example above, "LastName" will always contain
exactly fifteen characters; of course, there may be anywhere from 0 to
15 trailing SPACES as part of the current LastName value.

C actually has no "string" datatype; it stores strings as an array of
"char" datatype items where each element of the array is a single
character.  Being an array, there is an upper limit to how many
characters may be stored in a given "string".  For example:

   char lastName[15]; /* 15 chars: lastName[0] thru lastName[14] */

C provides a robust set of string-manipulation functions to copy
strings from one char array to another, search strings for certain
characters, compare one char array to another, concatenate char arrays
and so forth.  To make these functions possible, it was necessary to be
able to define the logical end of a string.  C accomplishes this via
the expectation that all strings (char arrays) will be terminated by a
NULL character (x'00').  Of course, no one forces a programmer to do
this, but if [s]he ever expects to use any of the C standard functions
to manipulate that string they had better be null-terminating their
strings!

So, GNU COBOL programmers expecting to pass strings to or receive
strings from C programs had best be prepared to deal with the
null-termination issue, as follows:

  1. Pass a quoted literal string from GNU COBOL to C as a
     zero-delimited string literal (Z'<string>').

  2. Pass alphanumeric (PIC X) or alphabetic (PIC A) data items to C
     subroutines by appending an ASCII NULL character (X'00') to them.
     For example, to pass the 15-character LastName data item described
     above to a C subroutine:

          01  LastName-Arg-to-C     PIC X(16).
          ...
              MOVE FUNCTION CONCATENATE(LastName,X'00') TO LastName-Arg-to-C

     And then pass LastName-Arg-to-C to the C subprogram!

  3. When a COBOL program needs to process string data prepared by a C
     program, the imbedded null character must be accounted for.  This
     can easily be accomplished with an "INSPECT" statement (see
     INSPECT) such as the following:

          INSPECT Data-From-a-C-Program
              REPLACING FIRST X'00' BY SPACE
                        CHARACTERS BY SPACE AFTER INITIAL X'00'

9.9.3. Matching C Data Types with GNU COBOL USAGEs
--------------------------------------------------

Matching up GNU COBOL numeric USAGEs with their C language data type
equivalents is possible via the following chart:

COBOL                                C
--------------------------------------------------------------------------
BINARY-CHAR [ UNSIGNED ]             unsigned char

BINARY-CHAR SIGNED                   signed char

BINARY-SHORT [ UNSIGNED ]            unsigned
                                     unsigned int
                                     unsigned short
                                     unsigned short int

BINARY-CHAR [ UNSIGNED ]             unsigned char

BINARY-CHAR SIGNED                   signed char

BINARY-SHORT [ UNSIGNED ]            unsigned
                                     unsigned int
                                     unsigned short
                                     unsigned short int

BINARY-SHORT SIGNED                  int
                                     short
                                     short int
                                     signed int
                                     signed short
                                     signed short int

BINARY-LONG [ UNSIGNED ]             unsigned long
                                     unsigned long int

BINARY-LONG SIGNED                   long
BINARY-INT                           long int
                                     signed long
                                     signed long int

BINARY-C-LONG SIGNED                 long

BINARY-DOUBLE [ UNSIGNED ]           unsigned long long
                                     unsigned long long int

BINARY-DOUBLE SIGNED                 long long int
BINARY-LONG-LONG                     signed long long int

COMPUTATIONAL-1                      float

COMPUTATIONAL-2                      double

N/A (no GNU COBOL equivalent)        long double

These are the ANSI2002 standard specifications for C-program data
compatibility and GNU COBOL programmers should get used to using them
when data is being shared with C programs (they're good documentation
too, highlighting the fact that the data will be "shared" with a C
program).

9.9.4. GNU COBOL Main Programs CALLing C Subprograms
----------------------------------------------------

Here's a sample of a GNU COBOL program that CALLs a C subprogram.

COBOL Calling Program               C Called Program
==================================  ===============================
IDENTIFICATION DIVISION.            #include <stdio.h>
PROGRAM-ID. maincob.                int subc(char *arg1,
DATA DIVISION.                               char *arg2,
WORKING-STORAGE SECTION.                     unsigned long *arg3) {
01  Arg1     PIC X(7).                char nu1[7]="New1";
01  Arg2     PIC X(7).                char nu2[7]="New2";
01  Arg3     USAGE BINARY-LONG.       printf("Starting subc\n");
PROCEDURE DIVISION.                   printf("Arg1=%s\n",arg1);
000-Main.                             printf("Arg2=%s\n",arg2);
    DISPLAY 'Starting maincob'        printf("Arg3=%d\n",*arg3);
    MOVE Z'Arg1'   TO Arg1            arg1[0]='X';
    MOVE Z'Arg2'   TO Arg2            arg2[0]='Y';
    MOVE 123456789 TO Arg3            *arg3=987654321;
    CALL 'subc'                       return 2;
        USING BY CONTENT   Arg1,    }
              BY REFERENCE Arg2,
              BY REFERENCE Arg3
    DISPLAY 'Back'
    DISPLAY 'Arg1=' Arg1
    DISPLAY 'Arg2=' Arg2
    DISPLAY 'Arg3=' Arg3
    DISPLAY 'Returned value='
            RETURN-CODE
    STOP RUN
    .

The idea is to pass two string and one full-word unsigned arguments to
the subprogram, have the subprogram print them out, change all three
and pass a return code of 2 back to the caller.  The caller will then
re-display the three arguments (showing changes only to the two "BY
REFERENCE" arguments), display the return code and halt.

While simple, these two programs illustrate the techniques required
quite nicely.

Note how the COBOL program ensures that a null end-of-string terminator
is present on both string arguments.

Since the C program is planning on making changes to all three
arguments, it declares all three as pointers in the function header and
references the third argument as a pointer in the function body.  It
actually had no choice for the two string (char array) arguments -–
they must be defined as pointers in the function even though the
function code references them without the leading “*” that normally
signifies pointers.

These programs are compiled and executed as follows.

     $ cobc -x maincob.cbl subc.c
     $ maincob
     Starting maincob
     Starting subc
     Arg1=Arg1
     Arg2=Arg2
     Arg3=123456789
     Back
     Arg1=Arg1
     Arg2=Yrg2
     Arg3=+0987654321
     Returned value=+000000002
     $

Remember that the null characters are actually in the GNU COBOL "Arg1"
and "Arg2" data items.  They don't appear in the output, but they ARE
there.

Did you notice the output showing the contents of "Arg1" after the
subroutine was called?  Those contents were unchanged!  The subroutine
definitely changed that argument, but since the COBOL program passed
that argument "BY CONTENT", the change was made to a copy of the
argument, not to the "Arg1" data item itself.

9.9.5. C Main Programs Calling GNU COBOL Subprograms
----------------------------------------------------

Now, the roles of the two languages in the previous section will be
reversed, having a C main program execute a GNU COBOL subprogram.

C Calling Program                              GNU-COBOL Called Program
=============================================  =================================
#include <libcob.h> /* COB RUN-TIME */         IDENTIFICATION DIVISION.
#include <stdio.h>                             PROGRAM-ID. subcob.
int main (int argc, char **argv) {             DATA DIVISION.
   int returnCode;                             LINKAGE SECTION.
   char arg1[7] = "Arg1";                      01  Arg1      PIC X(7).
   char arg2[7] = "Arg2";                      01  Arg2      PIC X(7).
   unsigned long arg3 = 123456789;             01  Arg3      USAGE BINARY-LONG.
   printf("Starting mainc...\n");              PROCEDURE DIVISION USING
   cob_init (argc, argv); /* COB RUN-TIME */       BY VALUE     Arg1,
   returnCode = subcob(arg1,arg2,&arg3);           BY REFERENCE Arg2,
   printf("Back\n");                               BY REFERENCE Arg3.
   printf("Arg1=%s\n",arg1);                   000-Main.
   printf("Arg2=%s\n",arg2);                       DISPLAY 'Starting cobsub.cbl'
   printf("Arg3=%d\n",arg3);                       DISPLAY 'Arg1=' Arg1
   printf("Returned value=%d\n",returnCode);       DISPLAY 'Arg2=' Arg2
   return returnCode;                              DISPLAY 'Arg3=' Arg3
}                                                  MOVE 'X' TO Arg1 (1:1)
                                                   MOVE 'Y' TO Arg2 (1:1)
                                                   MOVE 987654321 TO Arg3
                                                   MOVE 2 TO RETURN-CODE
                                                   GOBACK
                                                   .

Since the C program is the one that will execute first, before the GNU
COBOL subroutine, the burden of initializing the GNU COBOL run-time
environment lies with that C program; it will have to invoke the
"cob_init" function, which is part of the "libcob" library.  The two
required C statements are shown highlighted.

The arguments to the "cob_init" routine are the argument count and
value parameters passed to the main function when the program began
execution.  By passing them into the GNU COBOL subprogram, it will be
possible for that GNU COBOL program to retrieve the command line or
individual command-line arguments.  If that won't be necessary,
"cob_init(0,NULL);" could be specified instead.

Since the C program wants to allow "arg3" to be changed by the
subprogram, it prefixes it with a "&" to force a CALL BY REFERENCE for
that argument.  Since "arg1" and "arg2" are strings (char arrays), they
are automatically passed by reference.

Here's the output of the compilation process as well as the program's
execution.  The example assumes a Windows system with a GNU COBOL build
that uses the GNU C compiler on that system; the technique works
equally well regardless of which C compiler and which operating system
you're using.

     C:\Users\Gary\Documents\Programs> cobc -S subcob.cbl
     C:\Users\Gary\Documents\Programs> gcc mainc.c subcob.s -o mainc.exe -llibcob
     C:\Users\Gary\Documents\Programs> mainc.exe
     Starting mainc...
     Starting cobsub.cbl
     Arg1=Arg1
     Arg2=Arg2
     Arg3=+0123456789
     Back
     Arg1=Xrg1
     Arg2=Yrg2
     Arg3=987654321
     Returned value=2
     C:\Users\Gary\Documents\Programs>

Note that even though we told GNU COBOL that the 1st argument was to be
"BY VALUE", it was treated as if it were "BY REFERENCE" anyway.  String
(char array) arguments passed from C callers to GNU COBOL subprograms
will be modifiable by the subprogram.  It's best to pass a copy of such
data if you want to ensure that the subprogram doesn't change it.

The third argument is different, however.  Since it's not an array you
have the choice of passing it either "BY REFERENCE" or "BY VALUE".

10. Programming Style Suggestions
*********************************

This chapter deals with a variety of stylistic issues that may be of
interest to someone who is just starting out learning and using COBOL.
Much of this chapter makes recommendations and suggestions for how to
write your own programs.  The sample programs in the "Sample Programs"
document (see gnucobsp.info) were coded using almost all
of these recommendations.

There's no particular order of importance to the topics presented
here.

10.1. Marking Changes in Programs
=================================

For quite a while now (back to the 1970s), the "sequence number area"
of a COBOL statement (columns 1-6) has come to be used as a change
indicator area.  Programmers would place a code in columns 1-6 of every
line they changed in a program.  The author works in a COBOL shop where
change indicators of the form "xxmmyy" are required on every altered
line of a program -- "xx" is the initials of the programmer while
"mmyy" are the month and two-digit year of the date the change was
made.  This is frequently accompanied by a comment block at or near the
top of a COBOL program providing general documentation of what changes
were made and what change indicator was used to mark that change.

The GCic sample program source listing (see GCic (gnucobsp.info))
provides an excellent example of such
documentation.

This technique of using columns 1-6 as a change indicator will ONLY
work if fixed source-record format is in effect.

Some COBOL shops prefer to use the eight-character Program Name Area
(columns 73-80) as a change code area.

Marking changes becomes more of a challenge when free-format source
code is in effect.  Creating a top-of-program comment block to
generically describe changes that have been made isn't difficult, even
in free-form.  What IS difficult, however, is coming up with a scheme
for per-statement markup of changes that doesn't introduce a
ridiculously excessive number of source lines to the program.  I'm not
sure there is a good answer to this problem (if a reader has one,
please let me know).  Generally, I've noticed that shops using
free-format conventions for their COBOL source tend to stick with just
the top-of-program comment block combined with minimal comment blocks
sprinkled throughout the program noting areas that underwent major
changes.

10.2. Data Item Coding and Naming Conventions
=============================================

When programs get very large, it becomes more and more challenging to
keep track of the data items that will be used in the program.  Here,
in no particular order of importance, are a variety of conventions that
can simplfy that problem.

Remember that the points described here are intended to make things
easier for you, the programmer.  No COBOL compiler cares one way or
another whether any of these suggestions are followed.

  1. Avoid the use of level 77 data items in new programs.  Once (1968
     and before) there were valid reasons for creating level-77 data
     items, but since the 1974 ANSI standard of COBOL there really
     hasn't been any reason why an elementary level-01 data item
     couldn't have been used instead of a level-77 item.

  2. Allocate level-01 data items in alphabetical sequence in the
     program source wherever practical.  This will make it vastly
     easier to locate the definitions of 01-level items in the program
     source without having to resort to a compilation cross-reference
     listing and/or text editor "find" command to locate them.

  3. Consider prefixing data items with an indication of where in the
     program structure they were created.  For example:

        * Start everything defined in the file section with "F-"

        * Start everything defined in working-storage with  "WS-"

        * Start everything defined in local-storage with "LS-"

        * Start everything defined in the linkage section with  "L-"

        * Start everything defined in the screen section with "S-"

        * Start everything defined in the report section with "R-"

     A convention such as this makes it simple, when you're reviewing
     code in the procedure division, to know in which section of the
     data division you should look in when locating the detailed
     description of a data item.  Once you're in the right division,
     coding convention #2 will assist in locating the data item
     definition.

  4. Consider including a trailing descriptor of the nature of all data
     items in their names.  The following chart presents a variety of
     such descriptors the author has encountered and used through the
     years.

    -ADDR

          The data item contains all or a part of an Address
          (City-ADDR, State-ADDR, Street-ADDR, ...)

    -BOOL

          A level-88 data item (which only has the value TRUE or
          FALSE)

    -CD

          A CODE whose value denotes information content above and
          beyond that of the mere value itself.  Some examples could be
          "Error-CD", "Status-CD", "Billing-CD"

    -CHR

          A data item containing a single character of data.

    -CONST

          A constant, specified as a level-78 data item, a level-01
          item with the CONST attribute

    -DT

          The data item contains a complete or partial date (Birth-DT,
          Birth-Month-DT, Birth-Year-DT, ...)

    -DTTM

          A data item containing both a date and a time

    -FILE

          A file name.  Note that these items would probably also have
          a "F-" prefix.

    -IDX

          A data item used as a table index (see section 10.3)

    -NM

          All or a portion of a person's name.  These could be extended
          to include business names, product names, etc.

    -PTR

          A data item whose USAGE is POINTER

    -NUM

          A generic numeric data item that doesn't fit into any of the
          other categories

    -QTY

          A count of something

    -REC

          An 01-level item defined in the FILE SECTION (constituting
          the layout of a record within a file). Note that these items
          would probably also have a "F-" prefix.

    -SCR

          The data item contains a complete or partial screen
          description (appropriate for SCREEN SECTION 01-level data
          items).

    -SUB

          A numeric item used as a table subscript (see section 10.3)

    -TEL

          All or part of a telephone number

    -TM

          The data item contains a complete or partial time value

    -TXT

          The data item contains generic alphanumeric text that doesn't
          fit into any of the other categories.

     The above is by no means an exhaustive list, but good programmers
     will use as few of these descriptors as possible as having too
     many defeats any benefits of such classification/documentation
     efforts.

  5. Consider including an acronym to be inserted into the name of any
     data item defined directly or indirectly subordinate to an
     01-level item, typically to be specified after any section-level
     tag, if you're using them.  For example, consider the names used
     in the following structure:

          01  WS-File-Status-Message-TXT.
              05 FILLER                     PIC X(13) VALUE 'Status Code: '.
              05 WS-FSM-Status-CD           PIC 9(2).
              05 FILLER                     PIC X(11) VALUE ', Meaning: '.
              05 WS-FSM-Msg-TXT             PIC X(25).

     The "-FSM-" acronyms make it easier to locate the description of
     the 01-item the status code and message text items belong to.

10.3. Table Subscripting versus Table Indexing
==============================================

The elements of a table may be referenced either using a subscript or
an index.  Syntactically, this is coded using parenthesis, as per the
following three examples, all of which store the letter "A" into the
17th occurrence of a data item named WSS-Output-Image-TXT:

  1. MOVE 'A' TO WSS-Output-Image-TXT (17)

  2. MOVE 17 TO WSS-OI-SUB
     MOVE 'A' TO WSS-Output-Image-TXT (WSS-OI-SUB)

  3. SET WSS-OI-IDX TO 17
     MOVE 'A' TO WSS-Output-Image-TXT (WSS-OI-IDX)

The 1st and 2nd examples are referred to as 'Subscripting' while the
3rd is known as 'Indexing'.  The distinction is fairly simple.

Indexing is the process of referencing an element of a table utilizing
a data item with an explicitly or implicitly defined "USAGE" (see
USAGE) of "INDEX" to select the desired occurrence, while ...

Subscripting is the process of referencing an element of a table
utilizing either a numeric constant or an unedited numeric data item to
select the desired occurrence.

Various implementations of COBOL generate object code that is quite
different in each of these three situations, and GNU COBOL is no
exception.

In general, table references such as example #1 (constant subscript)
generate the smallest, simplest  and fastest object code while table
references such as example #2 (numeric data item subscript) generate
the largest, most-complicated and slowest object code.

Table references such as example #3 (table indexing) generate object
code that falls in the middle of the other two but is far closer in
efficiency to example #1 than #2.

Some COBOL statements ("SEARCH" (see SEARCH), "SEARCH ALL" (see
SEARCH ALL) and the table-based "SORT" (see Table SORT)) require
you to index the affected table and to utilize that index with those
statements.  With any other references to tables, the choice is left to
the programmer as to which approach should be used.  In general, follow
these rules:

  1. Use constant subscripts (example #1) wherever possible/practical.

  2. If references to table elements are going to be performed many,
     many  times (tens or hundreds of thousands of times or more)
     during program execution, you will probably see a noticeable
     reduction in program execution time if you use indexing versus
     subscripting.

It's impossible to perform any arithmetic operation against an index
data item directly (other than a simple incrementation or
decrementation operation via the "SET UP/DOWN" statement (see SET UP/DOWN)).
Situations where any non-trivial computations are
required to calculate the effective occurrence number for a table
reference will require you to use a conventional unedited numeric data
item as the receiving field for the calculation.  That calculated value
would then need to be saved into the index data item via a "SET Index"
statement.

If you only need to use the computed occurrence number once, you might
as well just use the computed occurrence number data item as a
subscript.  If, however, you will need to use a computed "subscript"
many more times than once, the run-time overhead of converting that
occurrence value to an index (via "SET Index") will be worth the coding
effort.

Whew!

If references to table elements are not going to be performed many,
many times it probably won't make much difference whether you use
indexing or subscripting.

If you are comfortable with the "C" programming language, you might
find the following simple GNU COBOL program useful in exploring the
differences between subscripting and indexing:

     IDENTIFICATION DIVISION.
     PROGRAM-ID.  SUBVSINDEX.
     DATA DIVISION.
     WORKING-STORAGE SECTION.
     01  WS-TABLE-SUB                BINARY-LONG.
     01  WS-TABLE.
         05 WS-TABLE-ENTRY           OCCURS 20 TIMES
                                     INDEXED BY WS-TABLE-IDX
                                     PIC X(1).
     PROCEDURE DIVISION.
     000-Main SECTION.
     E1. MOVE 'A' TO WS-TABLE-ENTRY (17)
         .
     E2. MOVE 17 TO WS-TABLE-SUB
         MOVE 'A' TO WS-TABLE-ENTRY (WS-TABLE-SUB)
         .
     E3. SET WS-TABLE-IDX TO 17
         MOVE 'A' TO WS-TABLE-ENTRY (WS-TABLE-SUB)
         .

Compile this program as follows (the assumption is made that you are
executing the "cobc" command from the directory in which the above
program source code (subvsindex.cbl) exists.

                  cobc -C -save-temps subvsindex.cbl

After this command is executed, the file "subvsindex.c" will contain
the procedure division C code and "subvsindex.c.1.h" will contain the
working-storage C code.  Compare the generated C code for each of the
three "MOVE" statements.

10.4. Copybook Naming Conventions and Usage
===========================================

Since the intent of a copybook is to introduce COBOL code into a
particular spot in a program via the "COPY" statement (see COPY),
it is always a good idea to prefix copybook names with a character
sequence that identifies where in a program it's contents are intended
to be copyed.

For example:

"IDxxxxxxxx"

     Copybooks containing code intended for the identification
     division.  These will be rare as you almost never encounter copied
     code in the identification division.

"EDxxxxxxxx"

     Copybooks containing code intended for use in the environment
     division.  These copybooks are generally used for predefined
     "SPECIAL-NAMES" (see SPECIAL-NAMES) or "FILE-CONTROL" (see
     INPUT-OUTPUT SECTION) syntax,

"DDxxxxxxxx"
     Copybooks that contain data definitions.

"PDxxxxxxxx"
     Copybooks that contain executable instructions.

10.5. PROCEDURE DIVISION Sections Versus Paragraphs
===================================================

The issue of whether to use section and/or paragraph names
(collectively referred to as procedure names) within the procedure
division is one of near religious significance with many COBOL
programmers.

COBOL programming standards used by many organizations that use the
language generally call for procedure names to:

  1. Contain a leading numeric component (for example:
     "2000-Update-Customer"), AND...

  2. Be defined in the procedure division in non-decreasing sequence of
     that numeric component.

When you are looking at or editing any large COBOL program that has
been created with programming standards that include these two rules,
it is always a simple thing to know whether a reference to a procedure
is being made to code that exists before or after your current location
in the program, simply by comparing the numeric component of the
current procedure's name with the one in question.

Technically, GNU COBOL does not require ANY procedure names be defined
unless:

  1. You are using the "ALTER" statement (see ALTER) (the use of
     which should be avoided at all costs)

  2. You are using a procedural "PERFORM" statement (see Procedural PERFORM)

  3. You are using a "GO TO" statement (see GO TO)

  4. You are using a "MERGE" statement (see MERGE) with an "OUTPUT
     PROCEDURE"

  5. You are using a "SORT" statement (see SORT) with either (or
     both) an "INPUT PROCEDURE" or "OUTPUT PROCEDURE"

  6. You are using "DECLARATIVES" (see DECLARATIVES)

Since it is difficult to write any non-trivial COBOL program that uses
none of the above, lets assume you will be including at least one
section or paragraph in your GNU COBOL programs.

I like to use procedure division paragraphs and sections as follows:

  1. The very first procedure defined in the procedure division of my
     programs, assuming no "DECLARATIVES" (see DECLARATIVES) are
     defined, will be a section named "000-Main".  The declaration of
     this procedure will immediately follow the procedure division
     header (or "END DECLARATIVES" if "DECLARATIVES" are used).

  2. Any procedures referenced by "MERGE", "PERFORM", or "SORT"
     statements will be defined as sections.

  3. Any procedures referenced by "GO TO" statements will be defined as
     paragraphs, and those paragraphs will be defined in the same
     section as the "GO TO" statements that reference them.  In other
     words, "GO TO" statements may not be used to transfer control to a
     point in a different section.  This is NOT a GNU COBOL rule --
     this is my own personal programming practice intended to improve
     the readability and maintainability of my programs.

  4. I always include a numeric prefix to all procedure names I define,
     for the reasons stated earlier.

  5. I do not use "THRU" on any "MERGE", "PERFORM" or "SORT" statement
     unless the programming standards of the shop in which I am working
     require it.  My reasoning for this is that it is too easy to
     accidentally introduce a new procedure into the scope of a
     "THRU".

10.6. COMPUTE Versus ADD-SUBTRACT-MULTIPLY-DIVIDE
=================================================

Over the years, there has been much debate over the efficiency and
arithmetic accuracy of using the "COMPUTE" statement (see COMPUTE)
rather than the four basic  arithmetic operation statements.

Here are the facts -- draw your own conclusions as to which approach is
more appropriate under which circumstances.

  1. The "COMPUTE" statement supports exponentiation (via the "**"
     operator) -- there is no equivalent basic arithmetic statement.
     Although you could simulate integral exponentiation (raising a
     value to the third power, for example) using "MULTIPLY"
     statements, and you may use the "SQRT" intrinsic function (see
     SQRT) built-in intrinsic function to find a square root, there's
     just no (easy) way to find the cube-root of a value without using
     the "COMPUTE" statement.

  2. For non-trivial computations, "COMPUTE" statements "read" better.
     Take this, for example:

          COMPUTE R = (A + B * C) / D

     As compared to:

          MULTIPLY B BY C GIVING TEMP
          ADD A TO TEMP
          DIVIDE TEMP BY D GIVING R

     For non-trivial computations, "COMPUTE" statements may execute
     faster than the equivalent chain of basic arithmetic statements.
     For example, the COMPUTE statement shown above executes about 25%
     faster on my computer using GNU COBOL than does the
     MULTIPLY-ADD-DIVIDE sequence.

  3. For trivial computations, on the other hand, I prefer the inherent
     readability of a statement such as this:

          ADD 1 TO WSS-Input-Trans-QTY

     to this:

          COMPUTE WS-Input-Trans-QTY = WS-Input-Trans-QTY + 1

Appendix A - Glossary of Terms
******************************

'Alphabetic Data Item'

     A data item whose "PICTURE" clause allows it to contain only
     upper- and/or lower-case letters.  See PICTURE.

'Alphanumeric Data Item'

     A data item whose "PICTURE" clause allows it to contain absolutely
     any character whatsoever.  See PICTURE.  Group items (see
     Structured Data) are also implicitly considered to be
     alphanumeric data items.

'Alphanumeric Literal'

     A string of characters enclosed within a pair of quotation marks
     (") or apostrophes (').  See Alphanumeric Literals.

'Called Program'

     Another way to refer to a subprogram.  Note that a called program
     may also be a calling program.

'Calling Program'

     A program that executes a subprogram.  Note that a calling program
     may also be a called program.

'Collating Sequence'

     The sequence in which the characters that are acceptable to a
     computer are ordered for purposes of all types of sorting,
     merging, comparing, and processing.  GNU COBOL programs may
     utilize standard character-set collating sequences (such as that
     defined by the ASCII or EBCDIC charactersets) or
     programmer-defined custom sequences as specified in the
     OBJECT-COMPUTER paragraph (section 4.1.2) and defined in the
     SPECIAL-NAMES paragraph (section 4.1.4).

'Compilation Group'

     The collection of all compilation units being compiled by a single
     execution of the GNU COBOL compiler.

'Compilation Unit'

     A single source file being compiled by the GNU COBOL compiler.  A
     compilation unit may contain one or more programs.

'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 preceed
     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 preceeded by a control heading that states the full name
     and location of the store.

'Control Hierarchy'

     The natural hierarchy of control breaks within a RWCS-controlled
     report based upon the manner in which the data the report is being
     generated from is sorted.

'Copybook'

     A segment of program code that may be utilized by multiple
     programs simply by having that program use the COPY statement to
     import that code into the program.  Although similar to the
     "include" facility present in many other programming languages,
     the COBOL copybook mechanism is actually considerably more
     powerful.  See Copybooks, for a general discussion.  See
     COPY, for the specifics of the COPY statement.

'Data Item'

     A contiguous area of storage within the memory space of a program
     that may be referenced, by name, in a COBOL program.  Other
     programming languages use the term variable, property or attribute
     to describe the same concept.  See Structured Data.

'Detail Group'

     A report group that contains the detailed data being presented for
     the report.

'Detail Report'

     An RWCS-generated report to which at least one type of detail
     group is presented.

'Division'

     A collection of zero, one, or more sections of paragraphs, called
     the division body, that are formed and combined in accordance with
     a specific set of rules.  Each division consists of the division
     header and the related division body.  There are four divisions in
     a GNU COBOL program: Identification, Environment, Data, and
     Procedure (coded in that sequence).  See Program Structure.

'Dynamic Subprogram'

     A subprogram whose executable object code is contained in a
     different executable file as its calling program.  Dynamic
     subprograms are therefore loaded into memory as needed.

'Elementary Item'

     A data item that isn't itself comprised of other data items.
     See Structured Data.

'Entry-point'

     A spot in the procedure division where a program may begin
     execution when it is executed from the operating system, invoked
     as a user-defined function or called by another program.

     Every program has at least one entry-point -- known as the primary
     entry-point -- which corresponds to the first executable statement
     in the procedure division following the declaratives area, if
     any.

     Additional entry-points may be defined via the "ENTRY" statement
     (see ENTRY).

'Entry-point Name'

     Every entry-point has a name.  That name must be unique for all
     programs that comprise an executable program.  Entry-point names
     are defined using a subroutine's "PROGRAM-ID" paragraph, a
     user-defined function's "FUNCTION-ID" paragraph or via "ENTRY"
     (see ENTRY) statements coded in a subprogram's procedure
     division.

'Executable File'

     The GNU COBOL compiler can create operating-system appropriate
     files that may be executed directly from the operating system
     environment.  On Windows systems, these will be ".exe" files
     whereas on UNIX systems they will have no specific extensions.
     The compiler's "-x" switch is used to create executable files.
     Only main programs should be compiled in this manner.

'Execution Thread'

     The complete set of executable code that is run during the
     execution of a program.  This includes the main program as well as
     all executed subprograms, including those that are both
     dynamically and statically loaded.

'Figurative Constants'

     GNU COBOL, like other COBOL implementations, supports a number of
     reserved words that may be used to represent a specific literal
     value.  These are known as figurative constants.  See Figurative Constants,
     for more information.

'Fixed Format Mode'

     A mode of the GNU COBOL compiler's operation where source
     statements are constrained to meeting the pre-2002 standard of
     limiting COBOL statements to 80 columns, with various columns
     having limitations as to what sort of COBOL syntax could be
     specified in them.  See Format of Program Source Lines, for
     more information.

'Free Format Mode'

     A mode of the GNU COBOL compiler's operation where source
     statements are allowed to be as long as 255 characters, with no
     restrictions or requirements as to in which columns various syntax
     elements must appear.  See Format of Program Source Lines, for
     more information.

'Group Item'

     A hierarchical data structure where the group item -- itself a
     data item -- actually consists of two or more other contiguously
     allocated data items.  For example, 'Employee-Name' could be a
     35-character data item consisting of a 20-character 'Last-Name'
     data item followed by a 14-character 'First-Name' and a
     1-character 'Middle-Initial'.  See Structured Data.

'Hexadecimal Alphanumeric Literal'

     These are alphanumeric literals whose character sequence is
     specified by hexadecimal value.  These literals are formed by a
     quote- or apostrophe-delimited sequence of an even number of
     hexadecimal digits (upper- or lower-case), prefixed with the
     letter "X" (also upper- or lower-case).  For example, the
     character string "Demo" could be specified as the hexadecimal
     alphanumeric literal "X'44656D6F'", assuming the ASCII
     characterset.  See Alphanumeric Literals.

'Hexadecimal Numeric Literal'

     A numeric literal whose value is specified by hexadecimal value.
     These literals are formed by a quote- or apostrophe-delimited
     sequence of from 1 to 16 hexadecimal digits (upper- or
     lower-case), prefixed with the letter "H" (also upper- or
     lower-case).  For example, the number 123456 could be specified as
     the hexadecimal numeric literal "H'01E240'".  See Numeric Literals.

'Identifiers'

     These are data items a COBOL program will be working with.  The
     vast majority of identifiers are defined by the user (programmer)
     while a few are pre-defined by the GNU COBOL compiler.
     Identifiers pre-defined by the compiler are referred to as special
     registers.  Other programming languages generally refer to
     identifiers as "variables".

'Imperative Statement'

     Either a statement that begins with a non decision-making verb and
     specifies an unconditional action to be taken or a conditional
     verb such as "IF" or "EVALUATE", delimited by its explicit scope
     terminator (such as "END-IF" or "END-EVALUATE").  An imperative
     statement can consist of a sequence of imperative statements.

'Intrinsic Function'

     A built-in routine that accepts arguments and returns a value;
     syntactically, these may be used most places where GNU COBOL
     identifiers are valid.  See Intrinsic Functions, for
     documentation on all the GNU COBOL intrinsic functions.

'Level Number'

     A 1- or 2-digit number that indicates the hierarchical position of
     a data item in a group item or the special properties of a data
     description entry.

     Level numbers in the range 1 through 49 indicate the position of a
     data item in the hierarchical structure of a logical record.
     Level numbers in the range 1 through 9 can be written either as a
     single digit or as a zero followed by the significant digit.

     Level numbers 66, 77, 78 and 88 identify special properties of a
     data description entry.

'Literal'

     A generic term used for a constant value coded in a program that
     may be either a numeric literal or an alphanumeric literal.

'Main program'

     A program that is executed directly from an operating system or
     shell event.  Main programs are not executed from other programs
     (i.e. they are not called programs).

'National Characterset'

     A characterset that supports symbols using other than the
     traditional roman alphabet symbols used by the ASCII characterset.
     Typically, such a characterset uses a UTF-16 (i.e. 16
     bits-per-character) encoding of the Unicode characterset.

     Support for national charactersets in GNU COBOL is currently only
     partially implemented, and the compile- and run-time effect of
     using the "N" symbol in a "PICTURE" (see PICTURE) clause to
     define a field as containing national characters is the same as if
     "X(2)" had been coded, with the additional effect that such a
     field will qualify as a "NATIONAL" or "NATIONAL-EDITED" field on
     an "INITIALIZE" (see INITIALIZE) statement.

'Numeric Data Item'

     A data item whose "PICTURE" clause allows it to contain only the
     numeric digit characters "0"-"9" (signed or unsigned), or a data
     item whose "PICTURE"/"USAGE" combination allow it to contain
     actual binary numbers in integer, fixed-point, floating-point or
     packed-decimal format.  Numeric data items are the only ones that
     may be used as table subscripts or as source arguments on
     arithmetic statements.  "PICTURE" (see PICTURE), or "USAGE"
     (see USAGE).

'Numeric Edited Data Item'

     An otherwise numeric data item whose "PICTURE" (see PICTURE)
     clause also contains any of the editing symbols "$", "*", "+",
     ",", "-", ".", "/", "0" (zero), "B", "CR", "DB" or "Z".  Numeric
     edited data items are not eligible to serve as table subscripts or
     source arguments on arithmetic statements.

'Numeric Literal'

     A numeric constant.  See Numeric Literals.

'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:

        * The date the report was generated

        * The current page number of the report

'Page Heading'

     A report group that appears at the top of every page of an
     RWCS-generated report. Information typically found sithin such a
     report group might be:

        * A title for the report

        * The date the report was generated

        * The current page number of the report

        * Column headings describing the fields within the detail
          group(s)

'Primary Entry-Point'

     See entry-point.

'Procedure'

     All executable code statements within a single procedure division
     paragraph or section.

'Procedure name'

     A programmer-defined section or paragraph name in the procedure
     division assigned to a procedure.  Procedure names serve as a
     means by which a statement may refer to the statements that follow
     the procedure name.

'Program'

     A GNU COBOL main program or subprogram.

'Qualification'

     The process of establishing a unique reference to a data item
     whose name is duplicated in a program.  This takes the form of
     using the duplicated data name and the name of any of its parent
     data items, connected by "OF" or "IN" such that the combination of
     those two data names is unique within the program.

'Record'

     A group item that is not part of a higher-level group item.  See
     Data Definition Principles.  An elementary item with a level
     number of 01 can also be referred to as a record if it's
     definition occurs in the file section, provided that it's
     definition does not include the "CONSTANT" attribute.  See
     FILE-SECTION-Data-Item.

'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.

'Reserved Word'

     A word coded in a GNU COBOL program without any quote or
     apostrophe characters around it (which would have transformed that
     sequence of characters into a literal string) which has a very
     specific meaning to the compiler.  See Language Reserved Words,
     for a general discussion of the concept.  See Appendix B - Reserved Word List,
     for a complete list of GNU COBOL
     reserved words.

'Sentence'

     An arbitrarily long sequence of statements terminated by a
     period.

'Special Registers'

     Special data items that are automatically defined for your use by
     the GNU COBOL compiler.  See Special Registers, for a complete
     list.

'Statement'

     A single executable COBOL instruction.  All statements start with
     a verb ("DISPLAY", "IF", "MOVE", ...) which is followed by the
     operands and additional syntax elements that describe the actions
     to be performed.

'Static Subprogram'

     A subprogram whose executable object code is part of the same
     executable file as its calling program.  Static subprograms are
     therefore loaded into memory at the same time as their caller.

'Subprogram'

     A program invoked directly by another program in such a manner
     that it may return control back to the other program, directly
     back to the point where the subprogram was invoked.

'Subroutine'

     A subprogram executed from another via a GNU COBOL "CALL" (see
     CALL) statement (or the equivalent in whatever programming
     language that other program was written in).

'Summary Report'

     An RWCS-generated report to which no detail groups are presented.

'User-Defined Function'

     A subprogram written in GNU COBOL that is executed in a
     syntactically-similar manner to that by which the various built-in
     intrinsic functions are executed.

'User-Defined Names'

     Either the name of an identifier or a procedure in the program.
     GNU COBOL limits user-defined names to a maximum of 31 characters
     taken from the set of numeric digits, upper- and lower-case
     letters, hyphens and underscores.  A user-defined name may neither
     begin nor end with a hyphen or underscore.  User-defined names
     used as file names may additionally not begin with a digit
     although - unlike many other programming languages - user-defined
     names used as identifiers or procedure names may.

'Verb'

     The first reserved word of a COBOL statement.

'Zero-Delimited Alphanumeric Literals'

     An alphanumeric literal prefixed with an upper- or lower-case "Z"
     character -- for example, "Z'ABC'".  These literals are one
     character longer than the value within apostrophes or quotes would
     make them appear.  The extra character (the last character) will
     be a null character (comprised entirely of zero bits).  These
     literals are ideal when defining or assigning values to
     alphanumeric data items that will be passed as arguments to a C
     subroutine.  See Alphanumeric Literals.

Appendix B - Reserved Word List
*******************************

The following is the complete list of reserved words in the 23NOV2013
build of GNU COBOL 2.1.  Even though the functionality behind some of
these words may not be implimented in this version of GNU COBOL, none
may be used as any user-defined name.

*A*
     ABS, ACCEPT, ACCESS, ACOS, ACTIVE-CLASS, ADD, ADDRESS, ADVANCING,
     AFTER, ALIGNED, ALL, ALLOCATE, ALPHABET, ALPHABETIC,
     ALPHABETIC-LOWER, ALPHABETIC-UPPER, ALPHANUMERIC,
     ALPHANUMERIC-EDITED, ALSO, ALTER, ALTERNATE, AND, ANNUITY, ANY,
     ANYCASE, ARE, AREA, AREAS, ARGUMENT-NUMBER, ARGUMENT-VALUE,
     ARITHMETIC, AS, ASCENDING, ASCII, ASIN, ASSIGN, AT, ATAN,
     ATTRIBUTE, AUTHOR, AUTO, AUTO-SKIP, AUTOMATIC, AUTOTERMINATE,
     AWAY-FROM-ZERO

*B*
     B-AND, B-NOT, B-OR, B-XOR, BACKGROUND-COLOR, BACKGROUND-COLOUR,
     BASED, BEEP, BEFORE, BELL, BINARY, BINARY-C-LONG, BINARY-CHAR,
     BINARY-DOUBLE, BINARY-INT, BINARY-LONG, BINARY-LONG-LONG,
     BINARY-SHORT, BIT, BLANK, BLINK, BLOCK, BOOLEAN,
     BOOLEAN-OF-INTEGER, BOTTOM, BY, BYTE-LENGTH, BYTE-LENGTH

*C*
     C01, C02, C03, C04, C05, C06, C07, C08, C09, C10, C11, C12, CALL,
     CALL-CONVENTION, CANCEL, CAPACITY, CD, CENTER, CF, CH, CHAIN,
     CHAINING, CHAR, CHAR-NATIONAL, CHARACTER, CHARACTERS, CLASS,
     CLASS-ID, CLASSIFICATION, CLOSE, COB-CRT-STATUS, CODE, CODE-SET,
     COL, COLLATING, COLS, COLUMN, COLUMNS, COMBINED-DATETIME, COMMA,
     COMMAND-LINE, COMMIT, COMMON, COMMUNICATION, COMP, COMP-1, COMP-2,
     COMP-3, COMP-4, COMP-5, COMP-6, COMP-X, COMPUTATIONAL,
     COMPUTATIONAL-1, COMPUTATIONAL-2, COMPUTATIONAL-3,
     COMPUTATIONAL-4, COMPUTATIONAL-5, COMPUTATIONAL-X, COMPUTE,
     CONCATENATE, CONDITION, CONFIGURATION, CONSOLE, CONSTANT,
     CONTAINS, CONTENT, CONTINUE, CONTROL, CONTROLS, CONVERSION,
     CONVERTING, COPY, CORR, CORRESPONDING, COS, COUNT, CRT, CRT-UNDER,
     CSP, CURRENCY, CURRENCY-SYMBOL, CURRENT-DATE, CURSOR, CYCLE

*D*
     DATA, DATA-POINTER, DATE, DATE-COMPILED, DATE-MODIFIED,
     DATE-OF-INTEGER, DATE-TO-YYYYMMDD, DATE-WRITTEN, DAY,
     DAY-OF-INTEGER, DAY-OF-WEEK, DAY-TO-YYYYDDD, DE, DEBUGGING,
     DECIMAL-POINT, DECLARATIVES, DEFAULT, DELETE, DELIMITED,
     DELIMITER, DEPENDING, DESCENDING, DESTINATION, DETAIL, DISABLE,
     DISC, DISK, DISPLAY, DISPLAY-OF, DIVIDE, DIVISION, DOWN,
     DUPLICATES, DYNAMIC

*E*
     E, EBCDIC, EC, EGI, ELSE, EMI, EMPTY-CHECK, ENABLE, END,
     END-ACCEPT, END-ADD, END-CALL, END-CHAIN, END-COMPUTE, END-DELETE,
     END-DISPLAY, END-DIVIDE, END-EVALUATE, END-IF, END-MULTIPLY,
     END-OF-PAGE, END-PERFORM, END-READ, END-RECEIVE, END-RETURN,
     END-REWRITE, END-SEARCH, END-START, END-STRING, END-SUBTRACT,
     END-UNSTRING, END-WRITE, ENTRY, ENTRY-CONVENTION, ENVIRONMENT,
     ENVIRONMENT-NAME, ENVIRONMENT-VALUE, EO, EOL, EOP, EOS, EQUAL,
     EQUALS, ERASE, ERROR, ESCAPE, ESI, EVALUATE, EXCEPTION,
     EXCEPTION-FILE, EXCEPTION-FILE-N, EXCEPTION-LOCATION,
     EXCEPTION-LOCATION-N, EXCEPTION-OBJECT, EXCEPTION-STATEMENT,
     EXCEPTION-STATUS, EXCLUSIVE, EXIT, EXP, EXP10, EXPANDS, EXTEND,
     EXTERNAL

*F*
     FACTORIAL, FACTORY, FALSE, FD, FILE, FILE-CONTROL, FILE-ID,
     FILLER, FINAL, FIRST, FLOAT-BINARY-128, FLOAT-BINARY-32,
     FLOAT-BINARY-64, FLOAT-DECIMAL-16, FLOAT-DECIMAL-34,
     FLOAT-EXTENDED, FLOAT-INFINITY, FLOAT-LONG, FLOAT-NOT-A-NUMBER,
     FLOAT-SHORT, FOOTING, FOR, FOREGROUND-COLOR, FOREGROUND-COLOUR,
     FOREVER, FORMAT, FORMATTED-CURRENT-DATE, FORMATTED-DATE,
     FORMATTED-DATETIME, FORMATTED-TIME, FORMFEED, FRACTION-PART, FREE,
     FROM, FULL, FUNCTION, FUNCTION-ID, FUNCTION-POINTER

*G*
     GENERATE, GET, GIVING, GLOBAL, GO, GOBACK, GREATER, GROUP,
     GROUP-USAGE

*H*
     HEADING, HIGH-VALUE, HIGH-VALUES, HIGHEST-ALGEBRAIC, HIGHLIGHT

*I*
     I-O, I-O-CONTROL, ID, IDENTIFICATION, IF, IGNORE, IGNORING,
     IMPLEMENTS, IN, INDEX, INDEXED, INDICATE, INDIRECT, INHERITS,
     INITIAL, INITIALISE, INITIALISED, INITIALIZE, INITIALIZED,
     INITIATE, INPUT, INPUT-OUTPUT, INSPECT, INSTALLATION, INTEGER,
     INTEGER-OF-BOOLEAN, INTEGER-OF-DATE, INTEGER-OF-DAY,
     INTEGER-OF-FORMATTED-DATE, INTEGER-PART, INTERFACE, INTERFACE-ID,
     INTERMEDIATE, INTO, INTRINSIC, INVALID, INVOKE, IS

*J*
     JUST, JUSTIFIED

*K*
     KEPT, KEY, KEYBOARD

*L*
     LABEL, LAST, LC_ALL, LC_COLLATE, LC_CTYPE, LC_MESSAGES,
     LC_MONETARY, LC_NUMERIC, LC_TIME, LEADING, LEFT, LEFT-JUSTIFY,
     LEFTLINE, LENGTH, LENGTH, LENGTH-AN, LENGTH-CHECK, LESS, LIMIT,
     LIMITS, LINAGE, LINAGE-COUNTER, LINE, LINE-COUNTER, LINES,
     LINKAGE, LOCAL-STORAGE, LOCALE, LOCALE-COMPARE, LOCALE-DATE,
     LOCALE-TIME, LOCALE-TIME-FROM-SECONDS, LOCK, LOG, LOG10,
     LOW-VALUE, LOW-VALUES, LOWER, LOWER-CASE, LOWEST-ALGEBRAIC,
     LOWLIGHT

*M*
     MANUAL, MAX, MEAN, MEDIAN, MEMORY, MERGE, MESSAGE, METHOD,
     METHOD-ID, MIDRANGE, MIN, MINUS, MOD, MODE, MODULE-CALLER-ID,
     MODULE-DATE, MODULE-FORMATTED-DATE, MODULE-ID, MODULE-PATH,
     MODULE-SOURCE, MODULE-TIME, MONETARY-DECIMAL-POINT,
     MONETARY-THOUSANDS-SEPARATOR, MOVE, MULTIPLE, MULTIPLY

*N*
     NAME, NATIONAL, NATIONAL-EDITED, NATIONAL-OF, NATIVE,
     NEAREST-AWAY-FROM-ZERO, NEAREST-EVEN, NEAREST-TOWARD-ZERO,
     NEGATIVE, NESTED, NEXT, NO, NO-ECHO, NONE, NORMAL, NOT, NULL,
     NULLS, NUMBER, NUMBER-OF-CALL-PARAMETERS, NUMBERS, NUMERIC,
     NUMERIC-DECIMAL-POINT, NUMERIC-EDITED,
     NUMERIC-THOUSANDS-SEPARATOR, NUMVAL, NUMVAL-C, NUMVAL-F

*O*
     OBJECT, OBJECT-COMPUTER, OBJECT-REFERENCE, OCCURS, OF, OFF,
     OMITTED, ON, ONLY, OPEN, OPTIONAL, OPTIONS, OR, ORD, ORD-MAX,
     ORD-MIN, ORDER, ORGANISATION, ORGANIZATION, OTHER, OUTPUT,
     OVERFLOW, OVERLINE, OVERRIDE

*P*
     PACKED-DECIMAL, PADDING, PAGE, PAGE-COUNTER, PARAGRAPH, PERFORM,
     PF, PH, PI, PIC, PICTURE, PLUS, POINTER, POSITION, POSITIVE,
     PREFIXED, PRESENT, PRESENT-VALUE, PREVIOUS, PRINTER, PRINTER,
     PRINTING, PROCEDURE, PROCEDURE-POINTER, PROCEDURES, PROCEED,
     PROGRAM, PROGRAM-ID, PROGRAM-POINTER, PROHIBITED, PROMPT,
     PROPERTY, PROTOTYPE, PURGE

*Q*
     QUEUE, QUOTE, QUOTES

*R*
     RAISE, RAISING, RANDOM, RANDOM, RANGE, RD, READ, RECEIVE, RECORD,
     RECORDING, RECORDS, RECURSIVE, REDEFINES, REEL, REFERENCE,
     REFERENCES, RELATION, RELATIVE, RELEASE, REM, REMAINDER, REMARKS,
     REMOVAL, RENAMES, REPLACE, REPLACING, REPORT, REPORTING, REPORTS,
     REPOSITORY, REQUIRED, RESERVE, RESET, RESUME, RETRY, RETURN,
     RETURN-CODE, RETURNING, REVERSE, REVERSE-VIDEO, REVERSED, REWIND,
     REWRITE, RF, RH, RIGHT, RIGHT-JUSTIFY, ROLLBACK, ROUNDED,
     ROUNDING, RUN

*S*
     SAME, SCREEN, SCROLL, SD, SEARCH, SECONDS,
     SECONDS-FROM-FORMATTED-TIME, SECONDS-PAST-MIDNIGHT, SECTION,
     SECURE, SECURITY, SEGMENT, SEGMENT-LIMIT, SELECT, SELF, SEND,
     SENTENCE, SEPARATE, SEQUENCE, SEQUENTIAL, SET, SHARING, SIGN,
     SIGN, SIGNED, SIGNED-INT, SIGNED-LONG, SIGNED-SHORT, SIN, SIZE,
     SORT, SORT-MERGE, SORT-RETURN, SOURCE, SOURCE-COMPUTER, SOURCES,
     SPACE, SPACE-FILL, SPACES, SPECIAL-NAMES, SQRT, STANDARD,
     STANDARD-1, STANDARD-2, STANDARD-BINARY, STANDARD-COMPARE,
     STANDARD-DECIMAL, STANDARD-DEVIATION, START, STATEMENT, STATIC,
     STATUS, STDCALL, STDERR, STDIN, STDOUT, STEP, STOP,
     STORED-CHAR-LENGTH, STRING, STRONG, SUB-QUEUE-1, SUB-QUEUE-2,
     SUB-QUEUE-3, SUBSTITUTE, SUBSTITUTE-CASE, SUBTRACT, SUM, SUM,
     SUPER, SUPPRESS, SW0, SW1, SW10, SW11, SW12, SW13, SW14, SW15,
     SW2, SW3, SW4, SW5, SW6, SW7, SW8, SW9, SWITCH-0, SWITCH-1,
     SWITCH-10, SWITCH-11, SWITCH-12, SWITCH-13, SWITCH-14, SWITCH-15,
     SWITCH-2, SWITCH-3, SWITCH-4, SWITCH-5, SWITCH-6, SWITCH-7,
     SWITCH-8, SWITCH-9, SYMBOL, SYMBOLIC, SYNC, SYNCHRONISED,
     SYNCHRONIZED, SYSERR, SYSIN, SYSIPT, SYSLIST, SYSLST, SYSOUT,
     SYSTEM-DEFAULT

*T*
     TABLE, TALLYING, TAN, TAPE, TERMINAL, TERMINATE, TEST,
     TEST-DATE-YYYYMMDD, TEST-DAY-YYYYDDD, TEST-FORMATTED-DATETIME,
     TEST-NUMVAL, TEST-NUMVAL-C, TEST-NUMVAL-F, TEXT, THAN, THEN,
     THROUGH, THRU, TIME, TIME-OUT, TIMEOUT, TIMES, TO, TOP,
     TOWARD-GREATER, TOWARD-LESSER, TRAILING, TRAILING-SIGN, TRANSFORM,
     TRIM, TRUE, TRUNCATION, TYPE, TYPEDEF

*U*
     UCS-4, UNDERLINE, UNIT, UNIVERSAL, UNLOCK, UNSIGNED, UNSIGNED-INT,
     UNSIGNED-LONG, UNSIGNED-SHORT, UNSTRING, UNTIL, UP, UPDATE, UPON,
     UPPER, UPPER-CASE, USAGE, USE, USER, USER-DEFAULT, USING, UTF-16,
     UTF-8

*V*
     VAL-STATUS, VALID, VALIDATE, VALIDATE-STATUS, VALUE, VALUES,
     VARIANCE, VARYING

*W*
     WAIT, WHEN, WHEN-COMPILED, WITH, WORDS, WORKING-STORAGE, WRITE

*Y*
     YEAR-TO-YYYY, YYYYDDD, YYYYMMDD

*Z*
     ZERO, ZERO-FILL, ZEROES, ZEROS

Appendix C - GNU Free Documentation License
*******************************************

                     Version 1.3, 3 November 2008

     Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
     `http://fsf.org/'

     Everyone is permitted to copy and distribute verbatim copies
     of this license document, but changing it is not allowed.

  0. PREAMBLE

     The purpose of this License is to make a manual, textbook, or other
     functional and useful document "free" in the sense of freedom: to
     assure everyone the effective freedom to copy and redistribute it,
     with or without modifying it, either commercially or
     noncommercially.  Secondarily, this License preserves for the
     author and publisher a way to get credit for their work, while not
     being considered responsible for modifications made by others.

     This License is a kind of "copyleft", which means that derivative
     works of the document must themselves be free in the same sense.
     It complements the GNU General Public License, which is a copyleft
     license designed for free software.

     We have designed this License in order to use it for manuals for
     free software, because free software needs free documentation: a
     free program should come with manuals providing the same freedoms
     that the software does.  But this License is not limited to
     software manuals; it can be used for any textual work, regardless
     of subject matter or whether it is published as a printed book.
     We recommend this License principally for works whose purpose is
     instruction or reference.

  1. APPLICABILITY AND DEFINITIONS

     This License applies to any manual or other work, in any medium,
     that contains a notice placed by the copyright holder saying it
     can be distributed under the terms of this License.  Such a notice
     grants a world-wide, royalty-free license, unlimited in duration,
     to use that work under the conditions stated herein.  The
     "Document", below, refers to any such manual or work.  Any member
     of the public is a licensee, and is addressed as "you".  You
     accept the license if you copy, modify or distribute the work in a
     way requiring permission under copyright law.

     A "Modified Version" of the Document means any work containing the
     Document or a portion of it, either copied verbatim, or with
     modifications and/or translated into another language.

     A "Secondary Section" is a named appendix or a front-matter section
     of the Document that deals exclusively with the relationship of the
     publishers or authors of the Document to the Document's overall
     subject (or to related matters) and contains nothing that could
     fall directly within that overall subject.  (Thus, if the Document
     is in part a textbook of mathematics, a Secondary Section may not
     explain any mathematics.)  The relationship could be a matter of
     historical connection with the subject or with related matters, or
     of legal, commercial, philosophical, ethical or political position
     regarding them.

     The "Invariant Sections" are certain Secondary Sections whose
     titles are designated, as being those of Invariant Sections, in
     the notice that says that the Document is released under this
     License.  If a section does not fit the above definition of
     Secondary then it is not allowed to be designated as Invariant.
     The Document may contain zero Invariant Sections.  If the Document
     does not identify any Invariant Sections then there are none.

     The "Cover Texts" are certain short passages of text that are
     listed, as Front-Cover Texts or Back-Cover Texts, in the notice
     that says that the Document is released under this License.  A
     Front-Cover Text may be at most 5 words, and a Back-Cover Text may
     be at most 25 words.

     A "Transparent" copy of the Document means a machine-readable copy,
     represented in a format whose specification is available to the
     general public, that is suitable for revising the document
     straightforwardly with generic text editors or (for images
     composed of pixels) generic paint programs or (for drawings) some
     widely available drawing editor, and that is suitable for input to
     text formatters or for automatic translation to a variety of
     formats suitable for input to text formatters.  A copy made in an
     otherwise Transparent file format whose markup, or absence of
     markup, has been arranged to thwart or discourage subsequent
     modification by readers is not Transparent.  An image format is
     not Transparent if used for any substantial amount of text.  A
     copy that is not "Transparent" is called "Opaque".

     Examples of suitable formats for Transparent copies include plain
     ASCII without markup, Texinfo input format, LaTeX input format,
     SGML or XML using a publicly available DTD, and
     standard-conforming simple HTML, PostScript or PDF designed for
     human modification.  Examples of transparent image formats include
     PNG, XCF and JPG.  Opaque formats include proprietary formats that
     can be read and edited only by proprietary word processors, SGML or
     XML for which the DTD and/or processing tools are not generally
     available, and the machine-generated HTML, PostScript or PDF
     produced by some word processors for output purposes only.

     The "Title Page" means, for a printed book, the title page itself,
     plus such following pages as are needed to hold, legibly, the
     material this License requires to appear in the title page.  For
     works in formats which do not have any title page as such, "Title
     Page" means the text near the most prominent appearance of the
     work's title, preceding the beginning of the body of the text.

     The "publisher" means any person or entity that distributes copies
     of the Document to the public.

     A section "Entitled XYZ" means a named subunit of the Document
     whose title either is precisely XYZ or contains XYZ in parentheses
     following text that translates XYZ in another language.  (Here XYZ
     stands for a specific section name mentioned below, such as
     "Acknowledgements", "Dedications", "Endorsements", or "History".)
     To "Preserve the Title" of such a section when you modify the
     Document means that it remains a section "Entitled XYZ" according
     to this definition.

     The Document may include Warranty Disclaimers next to the notice
     which states that this License applies to the Document.  These
     Warranty Disclaimers are considered to be included by reference in
     this License, but only as regards disclaiming warranties: any other
     implication that these Warranty Disclaimers may have is void and
     has no effect on the meaning of this License.

  2. VERBATIM COPYING

     You may copy and distribute the Document in any medium, either
     commercially or noncommercially, provided that this License, the
     copyright notices, and the license notice saying this License
     applies to the Document are reproduced in all copies, and that you
     add no other conditions whatsoever to those of this License.  You
     may not use technical measures to obstruct or control the reading
     or further copying of the copies you make or distribute.  However,
     you may accept compensation in exchange for copies.  If you
     distribute a large enough number of copies you must also follow
     the conditions in section 3.

     You may also lend copies, under the same conditions stated above,
     and you may publicly display copies.

  3. COPYING IN QUANTITY

     If you publish printed copies (or copies in media that commonly
     have printed covers) of the Document, numbering more than 100, and
     the Document's license notice requires Cover Texts, you must
     enclose the copies in covers that carry, clearly and legibly, all
     these Cover Texts: Front-Cover Texts on the front cover, and
     Back-Cover Texts on the back cover.  Both covers must also clearly
     and legibly identify you as the publisher of these copies.  The
     front cover must present the full title with all words of the
     title equally prominent and visible.  You may add other material
     on the covers in addition.  Copying with changes limited to the
     covers, as long as they preserve the title of the Document and
     satisfy these conditions, can be treated as verbatim copying in
     other respects.

     If the required texts for either cover are too voluminous to fit
     legibly, you should put the first ones listed (as many as fit
     reasonably) on the actual cover, and continue the rest onto
     adjacent pages.

     If you publish or distribute Opaque copies of the Document
     numbering more than 100, you must either include a
     machine-readable Transparent copy along with each Opaque copy, or
     state in or with each Opaque copy a computer-network location from
     which the general network-using public has access to download
     using public-standard network protocols a complete Transparent
     copy of the Document, free of added material.  If you use the
     latter option, you must take reasonably prudent steps, when you
     begin distribution of Opaque copies in quantity, to ensure that
     this Transparent copy will remain thus accessible at the stated
     location until at least one year after the last time you
     distribute an Opaque copy (directly or through your agents or
     retailers) of that edition to the public.

     It is requested, but not required, that you contact the authors of
     the Document well before redistributing any large number of
     copies, to give them a chance to provide you with an updated
     version of the Document.

  4. MODIFICATIONS

     You may copy and distribute a Modified Version of the Document
     under the conditions of sections 2 and 3 above, provided that you
     release the Modified Version under precisely this License, with
     the Modified Version filling the role of the Document, thus
     licensing distribution and modification of the Modified Version to
     whoever possesses a copy of it.  In addition, you must do these
     things in the Modified Version:

       A. Use in the Title Page (and on the covers, if any) a title
          distinct from that of the Document, and from those of
          previous versions (which should, if there were any, be listed
          in the History section of the Document).  You may use the
          same title as a previous version if the original publisher of
          that version gives permission.

       B. List on the Title Page, as authors, one or more persons or
          entities responsible for authorship of the modifications in
          the Modified Version, together with at least five of the
          principal authors of the Document (all of its principal
          authors, if it has fewer than five), unless they release you
          from this requirement.

       C. State on the Title page the name of the publisher of the
          Modified Version, as the publisher.

       D. Preserve all the copyright notices of the Document.

       E. Add an appropriate copyright notice for your modifications
          adjacent to the other copyright notices.

       F. Include, immediately after the copyright notices, a license
          notice giving the public permission to use the Modified
          Version under the terms of this License, in the form shown in
          the Addendum below.

       G. Preserve in that license notice the full lists of Invariant
          Sections and required Cover Texts given in the Document's
          license notice.

       H. Include an unaltered copy of this License.

       I. Preserve the section Entitled "History", Preserve its Title,
          and add to it an item stating at least the title, year, new
          authors, and publisher of the Modified Version as given on
          the Title Page.  If there is no section Entitled "History" in
          the Document, create one stating the title, year, authors,
          and publisher of the Document as given on its Title Page,
          then add an item describing the Modified Version as stated in
          the previous sentence.

       J. Preserve the network location, if any, given in the Document
          for public access to a Transparent copy of the Document, and
          likewise the network locations given in the Document for
          previous versions it was based on.  These may be placed in
          the "History" section.  You may omit a network location for a
          work that was published at least four years before the
          Document itself, or if the original publisher of the version
          it refers to gives permission.

       K. For any section Entitled "Acknowledgements" or "Dedications",
          Preserve the Title of the section, and preserve in the
          section all the substance and tone of each of the contributor
          acknowledgements and/or dedications given therein.

       L. Preserve all the Invariant Sections of the Document,
          unaltered in their text and in their titles.  Section numbers
          or the equivalent are not considered part of the section
          titles.

       M. Delete any section Entitled "Endorsements".  Such a section
          may not be included in the Modified Version.

       N. Do not retitle any existing section to be Entitled
          "Endorsements" or to conflict in title with any Invariant
          Section.

       O. Preserve any Warranty Disclaimers.

     If the Modified Version includes new front-matter sections or
     appendices that qualify as Secondary Sections and contain no
     material copied from the Document, you may at your option
     designate some or all of these sections as invariant.  To do this,
     add their titles to the list of Invariant Sections in the Modified
     Version's license notice.  These titles must be distinct from any
     other section titles.

     You may add a section Entitled "Endorsements", provided it contains
     nothing but endorsements of your Modified Version by various
     parties--for example, statements of peer review or that the text
     has been approved by an organization as the authoritative
     definition of a standard.

     You may add a passage of up to five words as a Front-Cover Text,
     and a passage of up to 25 words as a Back-Cover Text, to the end
     of the list of Cover Texts in the Modified Version.  Only one
     passage of Front-Cover Text and one of Back-Cover Text may be
     added by (or through arrangements made by) any one entity.  If the
     Document already includes a cover text for the same cover,
     previously added by you or by arrangement made by the same entity
     you are acting on behalf of, you may not add another; but you may
     replace the old one, on explicit permission from the previous
     publisher that added the old one.

     The author(s) and publisher(s) of the Document do not by this
     License give permission to use their names for publicity for or to
     assert or imply endorsement of any Modified Version.

  5. COMBINING DOCUMENTS

     You may combine the Document with other documents released under
     this License, under the terms defined in section 4 above for
     modified versions, provided that you include in the combination
     all of the Invariant Sections of all of the original documents,
     unmodified, and list them all as Invariant Sections of your
     combined work in its license notice, and that you preserve all
     their Warranty Disclaimers.

     The combined work need only contain one copy of this License, and
     multiple identical Invariant Sections may be replaced with a single
     copy.  If there are multiple Invariant Sections with the same name
     but different contents, make the title of each such section unique
     by adding at the end of it, in parentheses, the name of the
     original author or publisher of that section if known, or else a
     unique number.  Make the same adjustment to the section titles in
     the list of Invariant Sections in the license notice of the
     combined work.

     In the combination, you must combine any sections Entitled
     "History" in the various original documents, forming one section
     Entitled "History"; likewise combine any sections Entitled
     "Acknowledgements", and any sections Entitled "Dedications".  You
     must delete all sections Entitled "Endorsements."

  6. COLLECTIONS OF DOCUMENTS

     You may make a collection consisting of the Document and other
     documents released under this License, and replace the individual
     copies of this License in the various documents with a single copy
     that is included in the collection, provided that you follow the
     rules of this License for verbatim copying of each of the
     documents in all other respects.

     You may extract a single document from such a collection, and
     distribute it individually under this License, provided you insert
     a copy of this License into the extracted document, and follow
     this License in all other respects regarding verbatim copying of
     that document.

  7. AGGREGATION WITH INDEPENDENT WORKS

     A compilation of the Document or its derivatives with other
     separate and independent documents or works, in or on a volume of
     a storage or distribution medium, is called an "aggregate" if the
     copyright resulting from the compilation is not used to limit the
     legal rights of the compilation's users beyond what the individual
     works permit.  When the Document is included in an aggregate, this
     License does not apply to the other works in the aggregate which
     are not themselves derivative works of the Document.

     If the Cover Text requirement of section 3 is applicable to these
     copies of the Document, then if the Document is less than one half
     of the entire aggregate, the Document's Cover Texts may be placed
     on covers that bracket the Document within the aggregate, or the
     electronic equivalent of covers if the Document is in electronic
     form.  Otherwise they must appear on printed covers that bracket
     the whole aggregate.

  8. TRANSLATION

     Translation is considered a kind of modification, so you may
     distribute translations of the Document under the terms of section
     4.  Replacing Invariant Sections with translations requires special
     permission from their copyright holders, but you may include
     translations of some or all Invariant Sections in addition to the
     original versions of these Invariant Sections.  You may include a
     translation of this License, and all the license notices in the
     Document, and any Warranty Disclaimers, provided that you also
     include the original English version of this License and the
     original versions of those notices and disclaimers.  In case of a
     disagreement between the translation and the original version of
     this License or a notice or disclaimer, the original version will
     prevail.

     If a section in the Document is Entitled "Acknowledgements",
     "Dedications", or "History", the requirement (section 4) to
     Preserve its Title (section 1) will typically require changing the
     actual title.

  9. TERMINATION

     You may not copy, modify, sublicense, or distribute the Document
     except as expressly provided under this License.  Any attempt
     otherwise to copy, modify, sublicense, or distribute it is void,
     and will automatically terminate your rights under this License.

     However, if you cease all violation of this License, then your
     license from a particular copyright holder is reinstated (a)
     provisionally, unless and until the copyright holder explicitly
     and finally terminates your license, and (b) permanently, if the
     copyright holder fails to notify you of the violation by some
     reasonable means prior to 60 days after the cessation.

     Moreover, your license from a particular copyright holder is
     reinstated permanently if the copyright holder notifies you of the
     violation by some reasonable means, this is the first time you have
     received notice of violation of this License (for any work) from
     that copyright holder, and you cure the violation prior to 30 days
     after your receipt of the notice.

     Termination of your rights under this section does not terminate
     the licenses of parties who have received copies or rights from
     you under this License.  If your rights have been terminated and
     not permanently reinstated, receipt of a copy of some or all of
     the same material does not give you any rights to use it.

 10. FUTURE REVISIONS OF THIS LICENSE

     The Free Software Foundation may publish new, revised versions of
     the GNU Free Documentation License from time to time.  Such new
     versions will be similar in spirit to the present version, but may
     differ in detail to address new problems or concerns.  See
     `http://www.gnu.org/copyleft/'.

     Each version of the License is given a distinguishing version
     number.  If the Document specifies that a particular numbered
     version of this License "or any later version" applies to it, you
     have the option of following the terms and conditions either of
     that specified version or of any later version that has been
     published (not as a draft) by the Free Software Foundation.  If
     the Document does not specify a version number of this License,
     you may choose any version ever published (not as a draft) by the
     Free Software Foundation.  If the Document specifies that a proxy
     can decide which future versions of this License can be used, that
     proxy's public statement of acceptance of a version permanently
     authorizes you to choose that version for the Document.

 11. RELICENSING

     "Massive Multiauthor Collaboration Site" (or "MMC Site") means any
     World Wide Web server that publishes copyrightable works and also
     provides prominent facilities for anybody to edit those works.  A
     public wiki that anybody can edit is an example of such a server.
     A "Massive Multiauthor Collaboration" (or "MMC") contained in the
     site means any set of copyrightable works thus published on the MMC
     site.

     "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
     license published by Creative Commons Corporation, a not-for-profit
     corporation with a principal place of business in San Francisco,
     California, as well as future copyleft versions of that license
     published by that same organization.

     "Incorporate" means to publish or republish a Document, in whole or
     in part, as part of another Document.

     An MMC is "eligible for relicensing" if it is licensed under this
     License, and if all works that were first published under this
     License somewhere other than this MMC, and subsequently
     incorporated in whole or in part into the MMC, (1) had no cover
     texts or invariant sections, and (2) were thus incorporated prior
     to November 1, 2008.

     The operator of an MMC Site may republish an MMC contained in the
     site under CC-BY-SA on the same site at any time before August 1,
     2009, provided the MMC is eligible for relicensing.

ADDENDUM: How to use this License for your documents
====================================================

To use this License in a document you have written, include a copy of
the License in the document and put the following copyright and license
notices just after the title page:

       Copyright (C)  YEAR  YOUR NAME.
       Permission is granted to copy, distribute and/or modify this document
       under the terms of the GNU Free Documentation License, Version 1.3
       or any later version published by the Free Software Foundation;
       with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
       Texts.  A copy of the license is included in the section entitled ``GNU
       Free Documentation License''.

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
replace the "with...Texts." line with this:

         with the Invariant Sections being LIST THEIR TITLES, with
         the Front-Cover Texts being LIST, and with the Back-Cover Texts
         being LIST.

If you have Invariant Sections without Cover Texts, or some other
combination of the three, merge those two alternatives to suit the
situation.

If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of
free software license, such as the GNU General Public License, to
permit their use in free software.

Appendix D - Summary of Document Changes
****************************************

GNU COBOL is an ever-evolving tool.  While all reasonable attempts will
be made to maintain the currency of the information in this document,
neither the author of this document nor the authors of the GNU COBOL
software extend any warranties of any kind for this document or for the
information contained therein.

3rd Edition - 09 APR 2014

  1. The document has been converted to GNU Texinfo format, from which
     both GNU "info" and PDF files may be created for distribution.

  2. A new document -- "Sample Programs" -- has been created from the
     former "Sample Programs" chapter of this document.

  3. A new document -- "Quick Reference" -- has been introduced to
     provide a complete summary of all syntax diagrams.

3rd Edition - 01 MAY 2014

  1. Updated to include RWCS documentation, added with GNU COBOL 2.1.

  2. Removed the "See Also" links from all sections; with the Index now
     being fully hyperlinked, the maintenance of these links as well as
     the document size increase imposed by them is no longer justified.

2nd Edition - 17 JUL 2012

  1. Updated for version 23NOV2013 of GNU COBOL 2.0.

  2. Corrected a problem with several bogus footnote references.

  3. Added an International A4 page layout format version of the
     document, in addition to the US Letter page format version.

  4. The use of a slash character (“/”) in column 7 was documented –
     this feature has existed since at least the 06FEB2009 version of
     OpenCOBOL 1.1, but was undocumented.

  5. Added documentation on the DEBUG-ITEM special register.

  6. Updated DECLARATIVES documentation to better explain how to use it.

  7. A new section was added to the documentation to discuss the
     ramifications, rules and capabilities of sub-programming.

  8. Documentation was added on the COB_SET_DEBUG environment variable.

  9. The listings of all sample programs are now presented as listings
     generated by the GNU COBOL Interactive Compiler utility (itself
     included as a sample program).  This not only shows full source
     listings of the sample programs but complete cross-reference
     listings as well.

 10. A new sample program -– DAY-FROM-DATE -– was introduced to
     illustrate how to write a user-defined function.

 11. A reference to a new figure documenting error codes was added to
     the EXCEPTION-STATUS function.

 12. Documentation was added to the CLOSE statement to explicitly
     document how the last record written to a LINE SEQUENTIAL or LINE
     ADVANCING file may have a terminating delimiter sequence written
     at the time the file is closed.

 13. Documentation was added to the WRITE statement to explicitly
     document how the ADVANCING options are handled with LINE
     SEQUENTIAL and the new LINE ADVANCING files.

 14. Additional documentation on the cobcrun command was added.

 15. User-defined functions are now supported.

 16. A new built-in subroutine -– C$PRINTABLE -– was introduced (the
     COBDUMP sample program now uses it.

 17. LINE ADVANCING files are now supported.

 18. Floating-point literals of the form [+-]nn.nnE[+-]nn are now
     supported.

 19. Z”xxxxx” null-delimited alphanumeric literals are now supported.

 20. The COPY statement now supports the COBOL2002 standard LEADING and
     TRAILING options as well as the “IN/OF library-name” and SUPPRESS
     PRINTING options.

 21. The REPLACE Compiler-Directing Facility (CDF) statement was
     introduced.

 22. Conditional code generation is now supported through the use of
     >>DEFINE, >>IF, >>SET, >>SOURCE and >>TURN Compiler-Directing
     Facility (CDF) directives.

 23. The COB_LINE_TRACE environment variable was renamed to
     COB_SET_TRACE.

 24. The COB_DISPLAY_WARNINGS environment variable was introduced.

 25. SOURCE-COMPUTER WITH DEBUGGING MODE is now supported.

 26. The CHARACTER CLASSIFICATION clause of the OBJECT-COMPUTER clause
     is now supported.

 27. Mnemonic names are now optional for SWITCH declarations in
     SPECIAL-NAMES; Eight new switches (SWITCH-0, SWITCH-9 thru
     SWITCH-15) are now available; Switches may be specified as SW0
     thru SW15 as well as SWITCH-0 thru SWITCH-15; a new print channel
     designation of CSP is now available; SYMBOLIC CHARACTERS are now
     supported.

 28. The device name DISC may now be used interchangeably with DISK in
     SELECT statements.

 29. Files may now be SELECTed with the “NOT OPTIONAL” designation in
     addition to “OPTIONAL”.

 30. New USAGEs of BINARY-INT, BINARY-LONG-LONG and COMPUTATIONAL-6
     were introduced.

 31. The LEFTLINE screen attribute was added to the SCREEN SECTION.

 32. New  intrinsic functions were introduced:

        * MODULE-CALLER-ID

        * MODULE-DATE

        * MODULE-FORMATTED-DATE

        * MODULE-ID

        * MODULE-PATH

        * MODULE-SOURCE

        * MODULE-TIME

 33. A new option -- WITH KEPT LOCK -- was added to the READ verb.

 34. The following changes were made to the ACCEPT Statement:

        * The TIMEOUT option was added to Format 4.

        * The non-functional CONVERSION option was added to Format 4.

        * The LINE NUMBER option (a synonym for LINES) and COLS option
          (a synonym for COLUMNS) and ESCAPE KEY options were added to
          Format 6.

        * A new format -– Format 7 -– was introduced.

 35. The ALTER verb is now supported [Editorial Comment: this change
     was made only because NIST tests need it and not because you
     should be using it!]

 36. Options (mnemonic-name, STDCALL and STATIC) were added to the CALL
     verb.

 37. The non-functional CONVERSION option was added to Format 4 of the
     DISPLAY statement.

 38. The REVERSED option for the OPEN statement is now supported
     syntactically, even though it is non-functional.

 39. The READY TRACE and RESET TRACE statements were introduced.

 40. A new option -– STATUS –- was added to the STOP verb.

 41. The following built-in named subroutines were added:

        * C$CALLEDBY

        * C$GETPID

        * CBL_GET_CSR_POS

        * CBL_GET_SCR_SIZE

 42. The following built-in numbered subroutines were added:

        * X”E4”

        * X”E5”

1st Edition (Rev 2) - 17 SEP 2010

  1. Corrected “section 0” broken hyperlinks in the document.

  2. Introduced documentation for the hitherto undocumented "COBCPY"
     environment variable.

1st Edition (Rev 1) - 1 APR 2010

  1. Elaborated on the use of the GLOBAL clause in data item
     definitions.

1st Edition - 23 JAN 2010

  1. INITIAL RELEASE OF DOCUMENT – corresponds to OpenCOBOL 1.1,
     06FEB2009 version.