GnuCOBOL FAQ

GnuCOBOL FAQ banner

Index Tutorial


Dedicated to the living memory of Roger While (1950-2015)
Authors:
Brian Tiffin [btiffin]

Answers, quotes and contributions:
John Ellis [John], Vincent Coen, Jim Currey, Bill Klein [wmklein],
Ganymede, Rildo Pragana, Bill Woodger, Federico Priolo, Arnold Trembley
Frank Swarbrick, Angus, DamonH, Parhs, Gerald Chudyk, Steve Williams,
László Erdős, Reinhard Prehofer, Colin Duquesnoy, many others.

Compiler by:
Roger While [Roger],
Keisuke Nishida [Keisuke],
Ron Norman [Ron],
Sergey Kashyrin [Sergey],
Edward Hart [Hart],
Simon Sobisch [human],
Philipp Böhme,
Dave Pitts [Pitts],
Joe Robbins,
Luke Smith [Luke],
Brian Tiffin,
(with the invaluable assistance of many others)

Special credits to
Gary Cutler author of the GnuCOBOL Programmers Guide
Joseph James Frantz for hosting and advocacy [aoirthoir]
Version:

2.3.330, February 7th, 2017

Status:

never complete; like a limit, \lim_{aq\to0}f(aq) = 42

Copyright:

Copyright © 2008 Brian Tiffin

License:

This file is part of the GnuCOBOL FAQ.

This documentation is free; you can redistribute and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

This documentation is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this document. If not, see <http://www.gnu.org/licenses/>.

ChangeLog:

ChangeLog

Acknowledgment:

Below is a copy of the long standing acknowledgment request that appears in all versions of the CODASYL COBOL Journal of Development and most ANSI/ISO COBOL standards.

Any organization interested in reproducing the COBOL standard and
specifications in whole or in part, using ideas from this document as the basis
for an instruction manual or for any other purpose, is free to do so.  However,
all such organizations are requested to reproduce the following acknowledgment
paragraphs in their entirety as part of the preface to any such publication:

The COBOL standard acknowledgment, with respect and gratitude.

COBOL is an industry language and is not the property of any company or group
of companies, or of any organization or group of organizations.

No warranty, expressed or implied, is made by any contributor or by the CODASYL
COBOL Committee as to the accuracy and functioning of the programming system
and language.  Moreover, no responsibility is assumed by any contributor, or by
the committee, in connection therewith.

The authors and copyright holders of the copyrighted materials used herein

    FLOW-MATIC (trademark of Sperry Rand Corporation), Programming for the UNIVAC
    (R) I and II, Data Automation Systems copyrighted 1958, 1959, by Sperry Rand
    Corporation; IBM Commercial Translator Form No. F28-8013, copyrighted 1959 by
    IBM; FACT, DSI 27A5260-2760, copyrighted 1960 by Minneapolis-Honeywell

have specifically authorized the use of this material, in whole or in part, in
the COBOL specifications.  Such authorization extends to the reproduction and
use of COBOL specifications in programming manuals or similar publications.

Any organization using a short passage from this document, such as in a book
review, is requested to mention "COBOL" in acknowledgment of the source.

Many thanks to the original designers, supporting organizations, and individuals of the day.

Note

Regarding COBOL Standards, Official COBOL Standards: There are many references to standards in this document. Very few of them are technically correct references. Apologies to all the hard working men and women of the technical committees for this unintentional slight. For specific details on what wordings should be used please see What are the Official COBOL Standards?

1.1   What is GnuCOBOL?

GnuCOBOL is a free COBOL compiler. GnuCOBOL is a GNU software project.

GnuCOBOL implements a substantial part of the COBOL 85 and COBOL 2002 standards, as well as many extensions of the existent COBOL compilers.

GnuCOBOL translates COBOL into C and compiles the translated code using the configured C compiler, usually gcc. You can build your COBOL programs on various platforms, including Unix/Linux, Mac OS X, Microsoft Windows, OS/400, z/OS 390 mainframes, among others..

GnuCOBOL was OpenCOBOL. OpenCOBOL started around 2002, and on September 26th, 2013, GnuCOBOL was accepted and dubbed a GNU package by Dr. Richard Stallman. One day before the 30th anniversary of the GNU announcement.

The official page for GnuCOBOL is:

http://savannah.gnu.org/projects/gnucobol

A valuable reference, the GnuCOBOL Programmer's Guide can be found at GnuCOBOL Programmers Guide.

The original OpenCOBOL Programmer's Guide can be found at OpenCOBOL Programmers Guide.

In this author’s opinion, GnuCOBOL is a world class COBOL compiler, very capable with almost all of the COBOL 85 specifications, plus having some very internet ready, next generation potentials.

GnuCOBOL REDEFINES programming is the motto.

Coincidentally, that motto is compilable source code.

identification division.
program-id. motto.
data division.
working-storage section.

1, computer                                                   . 2
   programming value is "Highly rewarding".


2, GnuCOBOL REDEFINES programming                         pic xx.
                                                        procedure
                                                        division.
3. display GnuCOBOL.
prompt$ cobc -xj motto.cob
Hi

Ignore the tricky formatting, that was all for looks on a particular forum that only allows 52 characters on a line before scrolling. GnuCOBOL normally looks far more professional than the odd snippet of fun you may read in this document.

And a little marketing:

_images/cobc-marketing.png

1.2   What is COBOL?

COBOL is an acronym for COmmon Business Oriented Language. This author has always thought of it as “Common Business” Oriented more than Common “Business Oriented”, but that emphasis is perhaps up to the reader’s point of view.

As an aside: I’d like to steal the O in COmmon, and haven’t found a suitable word as of yet. Common Originally Business Oriented Language, was tried, trying to connote “it’s been extended”, but it sounds diminishing, like GnuCOBOL can’t do Business anymore. Which isn’t the case. So, the quest continues.

A discussion group posting on LinkedIn tweaked this again, Common Object Business Oriented Language. I like it. And with GnuCOBOL C++, perhaps Sergey can lead the charge/change.

Later... and even better, perhaps:

Common Objective Business Oriented Language.

A stable, business oriented language, that helps people meet the common objectives; across all the computing platforms, around the globe. That is not an official acronym or anything, just a suggestion.

1.3   How is GnuCOBOL licensed?

The compiler is licensed under the GNU General Public License.

The run-time library is licensed under GNU Lesser General Public License.

All source codes were copyright by the respective authors. With many thanks to Roger While and Keisuke Nishida for sharing their work with the world.

On June 17th, 2015, the legal transfer of all components of the GnuCOBOL
source code tree, from all authors, to the Free Software Foundation, was
announced as official.  The rights to copy the GnuCOBOL project source
codes are now in the care, and capable hands, of the FSF.

What this licensing means, roughly, is:

You are allowed to write GnuCOBOL programs that use the libcob run time
library however you like.  Closed, proprietary, commercial use is allowed as
part of the LGPL user freedoms.  You can ship GnuCOBOL generated programs in
binary form as you wish, (with exceptions; mentioned below).

Modifications to the compiler itself, if ever distributed, MUST provide
access to source code and be licensed under the GNU GPL.  Modifications to the
run time library code, if distributed to others, must also provide access to
the source code of the library changes, and be licensed under the LGPL. This
ensures that no one is allowed to close modified sources as their own, nor
deny anyone else the chance to copy and re-distribute the compiler source
code, including redistrubuted changes.  If modified sources are personal, or
never distributed outside an organization, there is no burden to release
the source.  The main intents of the GPL are to ensure end user freedoms.
And the LGPL code to be usable, as given, in closed run-time systems.

Berkeley Data Base license:

Please note: this applies to default GnuCOBOL binary builds.

Any verion of the compiler that is configured to use Berkeley DB
beyond version 1.85 must abide by the Oracle license, and sources of the
COBOL programs that use libdb must be shipped with any binaries. There are
alternatives to libdb, but deep down, GnuCOBOL encourages free software.

GnuCOBOL, by default is built with libdb for ISAM operations.  Be aware of
the implications, call Oracle, or build in something like the VBISAM engine.

GnuCOBOL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

Note

While GnuCOBOL can be held to a high standard of quality and robustness, the authors do not claim it to be a “Standard Conforming” implementation of COBOL.

1.4   What platforms are supported by GnuCOBOL?

OpenCobol 1.0 hosted on SourceForge.net, compiles on:

  • All 32-bit MS Windows (95/98/NT/2000/XP)
  • All POSIX (Linux/BSD/UNIX-like OSes)
  • OS/X

GnuCOBOL 1.1, the current official release version has been built on

  • MS Windows native
  • MS Windows with Cygwin
  • GNU/Linux
  • POSIX Systems including OpenSolaris
  • OS/X
  • AS/400
  • HP Integrity HPUX 11.23
  • RS600 AIX 5
  • 390 Mainframe z/OS OMVS/USS
  • others, Raspberry Pi (quote was $35 for hardware, OS and GnuCOBOL)

1.5   Are there pre-built GnuCOBOL packages?

Yes. Debian APT, and RPM packages exist. Packages for NetBSD. Many. Google opencobol packages for older builds, and gnu cobol for any late breaking news.

A Debian Advanced Package Tool binary package exists for GnuCOBOL 1.1 as open-cobol and lists dependencies of

  • libc6 (>= 2.7-1),
  • libcob1,
  • libcob1-dev (= 1.0-1),
  • libdb4.5 (>= 4.5.20-3),
  • libdb4.5-dev,
  • libgmp3-dev,
  • libgmp3c2,
  • libltdl3-dev,
  • libncurses5 (>= 5.6+20071006-3)

Thanks to the gracious efforts of Bart Martens, bartm on Debian’s .org domain.

Fedora and RedHat yum repositories usually have open-cobol as a choice for

yum install open-cobol

GnuCOBOL packages are slowly being introduced, and will likely see a revision from open-cobol-1.1 to GnuCOBOL 2.0 and gnucobol, after some release announcements and posting to GNU servers.

1.5.1   kiska.net repository

Also check out kiska.net for binary builds on various platforms. Thanks to Sergey Kashyrin, who is also the author of the version that emits C++ intermediates.

1.5.2   sourceforge

There are GnuCOBOL links at http://cobol.sourceforge.net

In particular, http://sourceforge.net/projects/cobol/files/open-cobol/ can come in handy, with sources and MinGW binaries at a minimum. Maybe more as time goes on.

1.5.3   Windows™ MinGW

Arnold Trembley put together an INNO installer, based on Gary Cutler’s MinGW builds of OpenCOBOL 1.1. Makes it pretty easy to get COBOL running on a PC. You can find it attached to SourceForge discussions, or at Arnold’s site:

1.5.4   MinGW official

An official GnuCOBOL project MinGW build, put together by Simon Sobisch, is stored on SourceForge, at

http://sourceforge.net/projects/open-cobol/files/gnu-cobol/1.1/ directly downloaded as

http://sourceforge.net/projects/open-cobol/files/gnu-cobol/1.1/GnuCOBOL_1.1_MinGW_BDB_PDcurses_MPIR.7z/download

As the name implies, this complete compiler build includes Berkeley DB for ISAM, PDCurses for extended screen IO, and MPIR for the decimal arithmetic and other multiprecision math features of GnuCOBOL.

This build is now also included in Colin’s OpenCOBOLIDE.

1.5.5   Windows™ Visual Studio vc11 native

Paraphrased from some posts by Simon on the forge:

New upload of http://sourceforge.net/projects/open-cobol/files/gnu-cobol/2.0/gnu-cobol-2.0_nightly_r411_win32_vc11_bin.7z - works correctly now

http://sourceforge.net/projects/open-cobol/files/gnu-cobol/win_prerequistes/win_prerequistes_vc11.7z was uploaded, too

Keep an eye on http://sourceforge.net/projects/open-cobol/files/gnu-cobol/2.0/ for the latest snapshots.

If you don't know already: GC translates COBOL to C and compiles it using a
C compiler. For Win8 I'd use VS2012 or higher (Express Versions work fine).
After installing it go to the downloads area and grab the first "official"
nightly build direct from svn: ... link above

it's quite easy to build GnuCOBOL 2.0 on your own: checkout 2.0-branch,
download the win_prerequisites from sourceforge download area, unpack it to
build_windows, open the VS solution you need (maybe changing defaults.h to
match your path) and click compile.

1.7   How complete is GnuCOBOL?

OpenCOBOL 1.0 implements a substantial portion of COBOL 85, supports many of the advances and clarifications of COBOL 2002, and includes many extensions in common use from Micro Focus COBOL, ACUCOBOL and other existent compilers.

GnuCOBOL 2.0 implements a more substantial portion of the COBOL 85 Dialect, COBOL 2002 and a growing number of vendor extensions. Some proposed COBOL 2014 features have also been implemented. Compatibility support includes:

  • MF for Micro Focus
  • IBM for IBM compatibility
  • MVS
  • BS2000

GnuCOBOL also includes some advanced features allowing source code such as

CALL "cfunction" USING BY REFERENCE ADDRESS OF VAR-IN-LINKAGE-SECTION.

Passing the equivalent of char**, pointer to pointer to char. Just as a small example of the level of coverage and flexibility provided by GnuCOBOL.

DISPLAY
    FUNCTION UPPER-CASE(
        FUNCTION SUBSTITUTE(
            "This is the orginal string.";
            "original"; "new"; "string"; "text"
        )
    )

Allowing for substitution of mixed length strings, something not normally so easy in COBOL. The above will output:

THIS IS THE NEW TEXT.

Note

While GnuCOBOL can be held to a high standard of quality and robustness, the authors do not claim it to be a “Standard Conforming” implementation of COBOL.

1.8   Will I be amazed by GnuCOBOL?

This author believes so. For a free implementation of COBOL, GnuCOBOL may surprise you in the depth and breadth of its COBOL feature support, usability and robustness.

COBOL has historically been very secretive and low key. Its domain of use being very secretive and low key. COBOL programmers rarely work on systems that would allow for open internet chat regarding details, let alone existence. It is a tribute to the professionalism of these programmers that most people rarely, if ever, hear the name COBOL, a programming language with billions of lines of source code compiled and in production around the world over half a century.

GnuCOBOL is poised to change that historic trend, and allow for the long overdue sharing of wisdom that legions of COBOL developers have accumulated over 50 years of success and failure. The GnuCOBOL conversation may be more POSIX than mainframe, but there is now room to share, critique and pass on the hard lessons learned from critical systems computing. Given that millions of COBOL programmers kept billions of lines of COBOL source out of the press, surely some of the wisdom can be passed on in a way that keeps all the secrets secret while curious developers are exposed to COBOL outside the vaults.

1.9   Who do I thank for GnuCOBOL?

Many people. In particular Keisuke Nishida, Roger While, Simon Sobisch, Ron Norman, and Sergey Kashyrin.

See the THANKS file in the source code archive for more names of people that have worked on the OpenCOBOL, now GnuCOBOL, project. Roger points out that the list is woefully incomplete. To quote:

The OC project would not have been where it is today without the
significant/enormous help from many-many persons. The THANKS
file does not even do justice to this.

1.10   Does GnuCOBOL include a Test Suite?

Why yes it does. 74 syntax tests, 170 coverage tests, and 16 data representation tests in the February 2009 pre-release.

88 syntax, 253 coverage, and 22 data tests in a 2010 cut. 456 tests in the 2014 sources, and growing. (501 tests in early 2015).

2.0-rc3 in early 2017 includes 34 general usage, 203 syntax, 21 listing, 409 coverage, and 26 data representation tests for a total of 693 test areas during build.

From a development tarball:

$ make check

will evaluate and report on the test suite. See make check listing for a current output listing of a test run.

make check is built with Autotools autotest, a Perl based test harness.

It supports a few options, one in particular:

$ TESTSUITEFLAGS='--jobs=4' make check

will run tests in parallel, pick a number appropriate to the number of cores.

A quad core pass with --jobs=4

00:24.86 elapsed 300%CPU

and without TESTSUITEFLAGS (some may be pre-cached etc...)

01:24.72 elapsed 100%CPU

85 seconds down to 25 seconds, when tested in parallel.

1.11   Does GnuCOBOL pass the NIST Test Suite?

Mostly. Not all. All attempted tests are passed. Over 9000.

The National Institute of Standards and Technology, NIST, maintained, and now archives a COBOL 85 implementation verification suite of tests. A compressed archive of the tests, last updated in 1993, to include Intrinsic Functions, can be found at

http://www.itl.nist.gov/div897/ctg/cobol_form.htm

GnuCOBOL passes many of the tests included in the NIST sponsored COBOL 85 test suite.

While the system successfully compiles over 400 modules, failing none of the over 9700 tests attempted; GnuCOBOL does not claim conformance to any level of COBOL Standard.

Instructions for use of the NIST suite is included in the build archive under:

tests/cobol85/README

Basically, it is a simple uncompress and make then sit back and relax. The scripts run GnuCOBOL over some 424 programs/modules and includes thousands of different, purposely complicated stress test passes.

It got easier too, just type make checkall during a source build to automatically download, extract and run the NIST test suite.

Test Modules
------------

Core tests:

  NC - COBOL nucleus tests
  SM - COPY sentence tests
  IC - CALL sentence tests

File I-O tests:

  SQ - Sequential file I-O tests
  RL - Relative file I-O tests
  IX - Indexed file I-O tests
  ST - SORT sentence tests
  SG - Segment tests

Advanced facilities:

  RW - REPORT SECTION tests
  IF - Intrinsic Function tests
  SG - Segment tests
  DB - Debugging facilities tests
  OB - Obsolete facilities tests

With the addition of GLOBAL support, the GnuCOBOL-reportwriter pre-release fails none of the attempted tests.

The summary.log from a run in November 2013 with initial Report Writer support:

------ Directory Information -------   --- Total Tests Information ---
Module Programs Executed Error Crash   Pass Fail Deleted Inspect Total
------ -------- -------- ----- -----  ----- ---- ------- ------- -----
NC           95       95     0     0   4371    0       4      26  4401
SM           17       17     0     0    293    0       2       1   296
IC           25       25     0     0    247    0       4       0   251
SQ           85       85     0     0    521    0       0      89   610
RL           35       35     0     0   1830    0       5       0  1835
IX           42       42     0     0    510    0       1       0   511
ST           40       40     0     0    289    0       0       0   289
SG           13       13     0     0    313    0       0       0   313
OB            7        7     0     0     34    0       0       0    34
IF           45       45     0     0    735    0       0       0   735
RW            6        6     0     0     42    0       0       0    42
DB           14       14     0     0    404    0       4      27   435
------ -------- -------- ----- -----  ----- ---- ------- ------- -----
Total       424      424     0     0   9589    0      20     143  9752

This is up from the 1.1 Feb 2009 release count of 9082.

1.11.1   What’s missing?

GnuCOBOL-reportwriter does not include support for:

Advanced facilities:

  CM - COMMUNICATION SECTION tests

and limits tests within the:

DB - Debugging facilities tests
OB - Obsolete facilities tests

sections.

1.12   What about GnuCOBOL and benchmarks?

COBOL has a legacy dating back to 1959. Many features of the COBOL standard provide defaults more suitable to mainframe architecture than the personal computer a 3rd millennium GnuCOBOL developer will likely be using.

GnuCOBOL, by default, generates code optimized for big-endian hardware. Fairly dramatic speed improvements on Intel architecture can come from simple USAGE IS COMPUTATIONAL-5 clauses in the DATA DIVISION.

1.12.1   telco billing

There is a benchmark posted at http://speleotrove.com/decimal/telco.html and thanks to Bill Klein [wmklein], there is a COBOL entry. From the source code listed below, you should only have to modify

Input-Output Section.
 File-Control.
    Select InFile  Assign to
         "C:\expon180.1e6".
    Select OutFile  Assign to
         "C:\TELCO.TXT"
                 Line
                 Sequential.

to point to the correct filename for your local copy of the benchmark million entry file and a suitable OutFile name for a clean compile and run.

Update: There is a version tuned for GnuCOBOL, especially the ROUNDED NEAREST-EVEN support. It gives correct results for what would be common default GnuCOBOL settings and compiler configurations, and Banker’s Rounding. Listed below.

In summary, the benchmark reads a large input file containing a suitably distributed list of telephone call durations (each in seconds). For each call, a charging rate is chosen and the price calculated and rounded to hundredths. One or two taxes are applied (depending on the type of call) and the total cost is converted to a character string and written to an output file. Running totals of the total cost and taxes are kept; these are displayed at the end of the benchmark for verification.

A run on an older pentium 4 and the million number file gave:

$ echo 'N' | time ./telco
Enter 'N' to skip calculations:
0.46user 1.08system 0:01.61elapsed 96%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+134776outputs (0major+345minor)pagefaults 0swaps

$ echo '' | time ./telco
Enter 'N' to skip calculations:
11.37user 1.41system 0:12.95elapsed 98%CPU (0avgtext+0avgdata 0maxresident)k
24inputs+134776outputs (0major+360minor)pagefaults 0swaps

$ tail TELCO.TXT
    35    D  |         0.31         0.02         0.01 |         0.34
   193    D  |         1.73         0.11         0.05 |         1.89
   792    L  |         1.03         0.06              |         1.09
   661    D  |         5.91         0.39         0.20 |         6.50
    44    L  |         0.06         0.00              |         0.06
   262    L  |         0.34         0.02              |         0.36
-------------+----------------------------------------+-------------
   Totals:   |   922,067.11    57,628.30    25,042.17 | 1,004,737.58
  Start-Time:09:37:23.93
    End-Time:09:37:36.83

2 seconds for the short test, 12 for the long, on a fairly small machine.

A more recent 1.1 pre-release, on a dual quad-core Xeon box running Linux SLES 10 64-bit:

$ tail TELCO.TXT
     35    D  |         0.31         0.02         0.01 |         0.34
    193    D  |         1.73         0.11         0.05 |         1.89
    792    L  |         1.03         0.06              |         1.09
    661    D  |         5.91         0.39         0.20 |         6.50
     44    L  |         0.06         0.00              |         0.06
    262    L  |         0.34         0.02              |         0.36
 -------------+----------------------------------------+-------------
    Totals:   |   922,067.11    57,628.30    25,042.17 | 1,004,737.58
   Start-Time:21:40:48.52
     End-Time:21:40:51.92

3.4 seconds cache-hot, long test. Not bad.

With Bill’s permission, the benchmark code is listed here: (with the first few lines added for the benefit of an indent based code highlighter)

COBOL
bench
mark
      *> 
      *> By William Klein, used with permission
      *>
       Identification Division.
        Program-ID. TELCO.
       Environment Division.
       Input-Output Section.
        File-Control.
           Select InFile  Assign to
                "C:\expon180.1e6".
      *>        "C:\TELCO.TEST".
           Select OutFile  Assign to
                "C:\TELCO.TXT"
                        Line
                        Sequential.
       Data Division.
        File Section.
       FD  InFile.
       01  InRec                Pic S9(15)      Packed-Decimal.
       01  InRec2.
           05                   Pic  X(7).
           05                   Pic S9(1)       Packed-Decimal.
             88  Premimum-Rate                  Value 1 3 5 7 9.
       FD  OutFile.
       01  OutRec               Pic X(70).
       Working-Storage Section.
       01  Misc.
           05                   Pic  X          Value "N".
             88  EOF                            Value "Y".
           05  Do-Calc          Pic  X          Value "Y".
             88  No-Calc                        Value "N".
           05.
               10  Start-Time   Pic X(21).
               10  End-Time     Pic X(21).
       01  Misc-Num.
           05  Price-Dec5       Pic S9(05)V9(06).
           05  Redefines Price-Dec5.
               10               Pic X(3).
               10               Pic S9(05).
                 88  Even-Round
                                Value 05000 25000 45000 65000 85000.
           05  Running-Totals.
               10  Price-Tot   Pic S9(07)V99    Binary.
               10  BTax-Tot    Pic S9(07)v99    Binary.
               10  DTax-Tot    Pic S9(07)V99    Binary  Value Zero.
               10  Output-Tot  Pic S9(07)V99    Binary.
           05  Temp-Num.
               10  Temp-Price   Pic S9(05)V99   Binary.
               10  Temp-Btax    Pic S9(05)V99   Binary.
               10  Temp-DTax    Pic S9(05)V99   Binary.
       01  WS-Output.
           05  Header-1         Pic X(70)       Value
               "  Time  Rate |        Price         Btax         Dtax |
      -        "      Output".
           05  Header-2         Pic X(70)       Value
               "-------------+----------------------------------------+-
      -        "------------".
           05  Detail-Line.
               10               Pic X(01)       Value Space.
               10  Time-Out     Pic zzzz9.
               10               Pic X(04)       Value Space.
               10  Rate-Out     Pic X.
               10               Pic X(04)       Value "  | ".
               10  Price-Out    Pic z,zzz,zz9.99.
               10               Pic X(01)       Value Spaces.
               10  Btax-Out     Pic z,zzz,zZ9.99.
               10               Pic X(01)       Value Spaces.
               10  Dtax-Out     Pic Z,zzz,zz9.99        Blank When Zero.
               10               Pic X(03)       Value " | ".
               10  Output-Out   Pic z,zzz,zZ9.99.
       Procedure Division.
        Mainline.
           Perform Init
           Perform Until EOF
               Read  InFile
                   At End
                       Set EOF  to True
                   Not At End
                       If No-Calc
                           Continue
                       Else
                           Perform  Calc-Para
                       End-If
                       Write OutRec from Detail-Line
               End-Read
           End-Perform
           Perform WindUp
           Stop Run
                .
       Calc-Para.
           Move InRec   to Time-Out
           If Premimum-Rate
               Move "D"         To Rate-Out
               Compute Temp-Price Rounded Price-Out Rounded Price-Dec5
                        = InRec * +0.00894
               Compute Temp-DTax DTax-Out
                        = Temp-Price * 0.0341
               Add Temp-Dtax to DTax-Tot
           Else
               Move "L"         To Rate-Out
               Compute Temp-Price Rounded Price-Out Rounded Price-Dec5
                        = InRec * +0.00130
               Move Zero to DTax-Out Temp-DTax
           End-If
           If Even-Round
               Subtract .01 from Temp-Price
               Move Temp-Price to Price-Out
           End-If
           Compute Temp-Btax BTax-Out
                        = Temp-Price * 0.0675
           Compute Output-Out
                        = Temp-Price + Temp-Btax + Temp-Dtax
           Add Temp-BTax        To Btax-Tot
           Add Temp-Price       to Price-Tot
           Compute Output-Tot
                        = Output-Tot + Function NumVal (Output-Out (1:))
               .
       Init.
           Open Input  InFile
                Output OutFile
           Write OutRec from Header-1
           Write OutRec from Header-2
           Display "Enter 'N' to skip calculations:" Upon Console
           Accept Do-Calc From Console
           Move Function Current-Date   To Start-Time
                .
       WindUp.
           Move Function Current-Date to End-Time
           Write OutRec         from Header-2
           Move Price-Tot       to Price-Out
           Move Btax-Tot        to Btax-Out
           Move Dtax-Tot        to Dtax-Out
           Move Output-Tot      to Output-Out
           Move "   Totals:"    to Detail-Line (1:12)
           Write OutRec         from Detail-Line
           Move Spaces          to OutRec
           String       "  Start-Time:"         Delimited by Size
                        Start-Time (9:2)        Delimited by Size
                        ":"                     Delimited by size
                        Start-Time (11:2)       Delimited by size
                        ":"                     Delimited by size
                        Start-Time (13:2)       Delimited by size
                        "."                     Delimited by size
                        Start-Time (15:2)       Delimited by size
                into OutRec
           Write OutRec
           Move Spaces          to OutRec
           String       "    End-Time:"         Delimited by Size
                        End-Time (9:2)          Delimited by Size
                        ":"                     Delimited by size
                        End-Time (11:2)         Delimited by size
                        ":"                     Delimited by size
                        End-Time (13:2)         Delimited by size
                        "."                     Delimited by size
                        End-Time (15:2)         Delimited by size
                into OutRec
           Write OutRec
           Close InFile
                 OutFile
                .

Download: listings/telco.cob

Data files and other code listings are copyright Mike Cowlishaw and IBM, so go to the speleotrove site, linked above, for all the details.

I’ll opine; Bill’s and Roger’s COBOL is a LOT easier to read than the other entries, being C, C#, Java. (The Turbo Pascal link seems broken, can’t speak to the readability), but I’m calling COBOL for the win on this one, wire to wire.

1.12.1.1   Roger’s telco benchmark update

Update
      *>
      *> By Roger While, used with permission
      *>
       IDENTIFICATION DIVISION.
       PROGRAM-ID. telco5.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT INFILE   ASSIGN TO
                "expon180.1e6"
                .
           SELECT OUTFILE  ASSIGN TO
                "TELCO.TXT"
                LINE SEQUENTIAL
                .
       DATA DIVISION.
       FILE SECTION.
       FD  INFILE.
       01  INREC            PIC S9(15)      PACKED-DECIMAL.
       01  INREC2.
           05               PIC  X(7).
           05               PIC  X.
             88  PREMIMUM-RATE
                    VALUES X"1C" X"3C" X"5C" X"7C" X"9C".
       FD  OUTFILE.
       01  OUTREC           PIC X(70).
       WORKING-STORAGE SECTION.
       01  DO-CALC          PIC X            VALUE "Y".
           88  NO-CALC                       VALUE "N".

       01  START-TIME       PIC X(21).
       01  END-TIME         PIC X(21).

       01  PRICE-TOT        PIC S9(07)V99    COMP-5.
       01  BTAX-TOT         PIC S9(07)V99    COMP-5.
       01  DTAX-TOT         PIC S9(07)V99    COMP-5.
       01  OUTPUT-TOT       PIC S9(07)V99    COMP-5.

       01  TEMP-PRICE       PIC S9(07)V99    COMP-5.
       01  TEMP-BTAX        PIC S9(07)V99    COMP-5.
       01  TEMP-DTAX        PIC S9(07)V99    COMP-5.

       01  HEADER-1         PIC X(70)       VALUE
           "  Time  Rate |        Price         Btax         Dtax | "
           &   "      Output".
       01  HEADER-2         PIC X(70)       VALUE
           "-------------+----------------------------------------+-"
           &   "------------".
       01  DETAIL-LINE.
           10               PIC X(01)         VALUE SPACE.
           10  NUMB-OUT     PIC ZZZZ9.
           10               PIC X(04)         VALUE SPACE.
           10  RATE-OUT     PIC X.
           10               PIC X(04)         VALUE "  | ".
           10  PRICE-OUT    PIC Z,ZZZ,ZZ9.99.
           10               PIC X(01)         VALUE SPACES.
           10  BTAX-OUT     PIC Z,ZZZ,ZZ9.99.
           10               PIC X(01)         VALUE SPACES.
           10  DTAX-OUT     PIC Z,ZZZ,ZZ9.99  BLANK WHEN ZERO.
           10               PIC X(03)         VALUE " | ".
           10  OUTPUT-OUT   PIC Z,ZZZ,ZZ9.99.
       PROCEDURE DIVISION.
       MAINLINE.
           OPEN INPUT  INFILE
                OUTPUT OUTFILE
           WRITE OUTREC FROM HEADER-1
           END-WRITE
           WRITE OUTREC FROM HEADER-2
           END-WRITE
           DISPLAY "Enter 'N' to skip calculations:" UPON CONSOLE
           END-DISPLAY
           ACCEPT DO-CALC FROM CONSOLE
           END-ACCEPT
       *>  Start timer
           MOVE FUNCTION CURRENT-DATE   TO START-TIME
       *>  Start loop
       *>  PERFORM UNTIL EXIT, changed to 0 = 1 for older compilers
           PERFORM UNTIL 0 = 1
               READ  INFILE AT END
                     EXIT PERFORM
               END-READ
               IF NOT NO-CALC
                   MOVE INREC   TO NUMB-OUT
                   IF PREMIMUM-RATE
                       MOVE "D"         TO RATE-OUT
                       COMPUTE TEMP-PRICE ROUNDED MODE NEAREST-EVEN
                                = INREC * 0.00894
                       END-COMPUTE
                       COMPUTE TEMP-DTAX
                                = TEMP-PRICE * 0.0341
                       END-COMPUTE
                       ADD TEMP-DTAX TO DTAX-TOT
                       END-ADD
                       MOVE TEMP-DTAX TO DTAX-OUT
                   ELSE
                       MOVE "L"         TO RATE-OUT
                       COMPUTE TEMP-PRICE ROUNDED MODE NEAREST-EVEN
                                = INREC * 0.00130
                       END-COMPUTE
                       MOVE ZERO TO TEMP-DTAX
                       MOVE ZERO TO DTAX-OUT
                   END-IF
                   MOVE TEMP-PRICE TO PRICE-OUT
                   COMPUTE TEMP-BTAX BTAX-OUT
                                = TEMP-PRICE * 0.0675
                   END-COMPUTE
                   ADD TEMP-PRICE TEMP-BTAX TEMP-DTAX TO OUTPUT-TOT
                   END-ADD
                   ADD TEMP-PRICE TEMP-BTAX TEMP-DTAX GIVING OUTPUT-OUT
                   END-ADD
                   ADD TEMP-BTAX        TO BTAX-TOT
                   END-ADD
                   ADD TEMP-PRICE       TO PRICE-TOT
                   END-ADD
               END-IF
               WRITE OUTREC FROM DETAIL-LINE
               END-WRITE
           END-PERFORM
       *>  End loop
       *>  End timer
           MOVE FUNCTION CURRENT-DATE TO END-TIME
           WRITE OUTREC         FROM HEADER-2
           END-WRITE
           MOVE PRICE-TOT       TO PRICE-OUT
           MOVE BTAX-TOT        TO BTAX-OUT
           MOVE DTAX-TOT        TO DTAX-OUT
           MOVE OUTPUT-TOT      TO OUTPUT-OUT
           MOVE "   Totals:"    TO DETAIL-LINE (1:12)
           WRITE OUTREC         FROM DETAIL-LINE
           END-WRITE
           MOVE SPACES          TO OUTREC
           STRING       "  Start-Time:"         DELIMITED BY SIZE
                        START-TIME (9:2)        DELIMITED BY SIZE
                        ":"                     DELIMITED BY SIZE
                        START-TIME (11:2)       DELIMITED BY SIZE
                        ":"                     DELIMITED BY SIZE
                        START-TIME (13:2)       DELIMITED BY SIZE
                        "."                     DELIMITED BY SIZE
                        START-TIME (15:2)       DELIMITED BY SIZE
                INTO OUTREC
           END-STRING
           WRITE OUTREC
           END-WRITE
           MOVE SPACES          TO OUTREC
           STRING       "    End-Time:"         DELIMITED BY SIZE
                        END-TIME (9:2)          DELIMITED BY SIZE
                        ":"                     DELIMITED BY SIZE
                        END-TIME (11:2)         DELIMITED BY SIZE
                        ":"                     DELIMITED BY SIZE
                        END-TIME (13:2)         DELIMITED BY SIZE
                        "."                     DELIMITED BY SIZE
                        END-TIME (15:2)         DELIMITED BY SIZE
                INTO OUTREC
           END-STRING
           WRITE OUTREC
           END-WRITE
           CLOSE INFILE
                 OUTFILE
           STOP RUN
           .

Download: listings/telco5.cob

1.13   Can GnuCOBOL be used for CGI?

Yes. Through standard IO redirection and the extended ACCEPT ... FROM ENVIRONMENT ... feature, GnuCOBOL is more than capable of supporting advanced Common Gateway Interface programming. See How do I use GnuCOBOL for CGI? for a sample Hello Web program.

Also see Can GnuCOBOL display the process environment space?

Here’s a screenshot of GnuCOBOL running in Apache server CGI, in the Cloud as a Juju Charm.

_images/gnucobol-charming.png

More specially, this screenshot was taken on a Fedora 19, XFCE desktop with a libvirt VM install of Ubuntu 13.04, running Firefox and browsing a locally spawned cloud instance. where the instantiation of the Juju Charm creates another virtual machine, installs a base operating system, compiles and installs GnuCOBOL with Report Writer, builds up a small testsuite of CGI ready COBOL applications, installs everything, starts apache and serves up the pages.

And it all just works

1.13.1   GnuCOBOL with FastCGI

FastCGI can also work with GnuCOBOL. A small wrinkle in the tectonics is that the standard IO C header file that is generated by cobc needs to be swapped out for fcgi_stdio.h. This isn’t too bad, as cobc can be used to generate intermediate C and after a quick text replacement, can then be called a second time to compile the generated C code into an executable suitable for placing in the web server space.

# Sample make rule for using FastCGI with GnuCOBOL
.RECIPEPREFIX = >

program: program.cob
> cobc -x -C program.cob
> sed -i 's/<stdio.h/<fcgi_stdio.h/' program.c
> LD_RUN_PATH=. cobc -x program.c -lfcgi

The CGI processing code then needs to add a simple looping structure internally.

*> FastCGI from COBOL sample
*>   fastcgi-accept is a binary-long
*>   carriage-return is x"0d" and newline is x"0a"
 procedure division.

 call "FCGI_Accept" returning fastcgi-accept
     on exception
         display
             "FCGI_Accept call error, link with -lfcgi"
         end-display
 end-call

 perform until fastcgi-accept is less than zero

*> Always send out the Content-type before any other IO
     display "Content-type: text/html" carriage-return newline
     end-display

     display "<html><body>" end-display
     display
         "<h3>FastCGI environment with GnuCOBOL</h3>"
     end-display

     ... rest of CGI handling ...

     call "FCGI_Accept" returning fastcgi-accept
         on exception
             move -1 to fastcgi-accept
     end-call

 end-perform

Some platforms (ala Cygwin) may need

call STATIC "FCGI_Accept" returning fastcgi-accept

to get proper linkage with libfcgi.

1.13.2   running on hosted services

For those developers looking to serve GnuCOBOL applications on hosted systems without super user privileges, see How do I use LD_RUN_PATH with GnuCOBOL? for some pointers on getting hosted executables installed properly. LD_RUN_PATH can make it easier for CGI programs to find a locally installed libcob runtime, something a hosted service may not provide.

1.14   Does GnuCOBOL support a GUI?

Yes, but not out of the box. There is not currently (January 2017) anything that ships with the product.

Third party extensions for Tcl/Tk and linkage to GTK+ and other frameworks do allow for graphical user interfaces. See Does GnuCOBOL support the GIMP ToolKit, GTK+? and Can GnuCOBOL interface with Tcl/Tk?.

1.14.1   GTK

The expectation is that GTK+ will be completely bound as a callable interface. That is currently (January 2017) not the case, with perhaps 2% of the GTK+ functionality wrapped (but with that 2%, fully functional graphical interfaces are possible).

_images/hellogtk.png

An experimental FUNCTION-ID wrapper is working out well

This procedure division: (part the of the library self-test)

cobweb
GTK+
       *> test basic windowing
        procedure division.
        move new-window("cobweb-gtk", width-hint, height-hint)
          to gtk-window-data
        move new-box(gtk-window, HORIZONTAL, spacing, homogeneous)
          to gtk-box-data
        move new-image(gtk-box, "blue66.png") to gtk-image-data
        move new-label(gtk-box, "And? ") to gtk-label-data
        move new-entry(gtk-box, "cobweb-entry-activated")
          to gtk-entry-data
        move new-button(gtk-box, "Expedite", "cobweb-button-clicked")
          to gtk-button-data
        move new-vte(gtk-box, vte-cols, vte-rows) to gtk-vte-data
        move new-spinner(gtk-box) to gtk-spinner-data

        move gtk-go(gtk-window) to extraneous
        goback.

produced

_images/cobweb-gui8.png

with the shell vte, being a fully functional terminal widget.

9 moves for a gui.

1.14.2   A GTK server

Peter van Eerten, author of BaCon, also develops an interpretive scripting interface to GTK. Commands are passed to the GLib/GTK libraries as text lines. A very COBOL friendly way of programming a Graphical User Interface. No external code is required, just READ and WRITE statements.

See GTK-server for a sample and download links. GTK-server can support GTK 1, GTK+ 2 and GTK+ 3 library installs and developers can customize which functions are available (along with sophisticated macros) in a simple and elegant configuration file.

1.14.3   Tcl/Tk

The Tcl/Tk engine by Rildo Pragana is already quite complete but does place most of the burden of GUI development squarely on the Tk side.

Another wrapper for Tcl/Tk is being developed for GnuCOBOL 2 that leverages User Defined Functions, and exposes an event loop to COBOL programmers.

1.14.4   Vala, WebKit

Vala will also open up a quick path to GUI development with GnuCOBOL. There is already an embedded web browser using the Vala bindings to WebKit. See Can GnuCOBOL interface with Vala? for a lot more details.

1.14.5   Redirect to browser

GDK 3 supports a backend called Broadway. Transform GTK desktop applications to websockets and HTML5 web guis. Here is a GnuCOBOL sample, written to explore the desktop GTK calendar widget, redirected to a browser using GDK Broadway, with clicks in the browser window invoking GnuCOBOL graphical event callback handlers, no change to the desktop application source code.

_images/cobwebgtk-broadway.png

More on this in A GTK+ calendar

Here is a GTK based interactive periodic table of the elements, written in GNU Cobol (6 lines of C support code), linked to GTK+ 3.0, and running with

broadwayd :1 &
BROADWAY_DISPLAY=:1 GDK_BACKEND=broadway ./cobweb-periodic

Without recompiling, the events and graphics are handled by the browser.

_images/cobweb-periodic-konqueror.png

See cobweb-periodic listing for the source code that produced that image. Please note that with recent changes to GTK+ theming, as of 3.16, the buttons are no longer properly coloured. New code needs to be written to provide CSS property management for GTK+ button colours.

1.14.6   X11

There are also a few examples of using X11 directly from GnuCOBOL. See Can GnuCOBOL interface with X11? for details.

1.14.7   Java AWT

Another very powerful option for graphics programming is available with the COBJAPI user defined function repository. See What is COBJAPI? for more information.

1.15   Does GnuCOBOL have an IDE?

IDE
Interactive Development Environment

Yes. (And no, there is no IDE that ships with the product but there is a contributor interactive development environment, written explicitly for GnuCOBOL). There are also other IDEs that support COBOL.

The add1tocobol team was working to create extensions for the GNAT Programming Studio. This was working out quite nicely, but more effort would be required to make this a viable alternative for GnuCOBOL developers.

See Can the GNAT Programming Studio be used with GnuCOBOL? for more information. Update: this effort is likely abondoned. See OpenCOBOLIDE, below, for the current leading, and project approved, GnuCOBOL IDE.

There is also the Eclipse IDE and a major project for integrating COBOL but this will not be GnuCOBOL specific.

Many text editors have systems in place for invoking compilers. SciTE, Crimson Editor, Vim and emacs, to name but a few of the dozens of programmer text editors that support edit/compile/test development cycles. See Kate for some notes and details on the GnuCOBOL development potentials in the KDE Advanced Text Editor.

See Does GnuCOBOL work with make? for some information on command line compile assistance.

1.15.1   OpenCOBOLIDE

There is a GnuCOBOL specific IDE getting good press, posted in PyPi at https://pypi.python.org/pypi/OpenCobolIDE

By Colin Duquesnoy. He just released version 4.7.6 (December 2016), and it now includes a MinGW binary build that Arnold Trembley helped put together for developers running Microsoft Windows. (see What is the current version of GnuCOBOL?)

Older news from Colin:

OpenCobolIDE 4.6.2 now includes this new build of GnuCOBOL:
https://launchpad.net/cobcide/4.0/4.6.2
(mirror: https://github.com/OpenCobolIDE/OpenCobolIDE/releases/tag/4.6.2)

Nice system. People like it. There have been over 12,000 downloads of the Windows installer. Which turns out to be a very quick and easy way to get up and running with GnuCOBOL in a Windows environment.

From Robert W. Mills, author of cobolmac, (See Does GnuCOBOL support source code macros?)

For the past week I have been using OpenCobolIDE to do all my GnuCOBOL
development. Being able to see your compile time errors while editing your
source is something I missed after I left the HPe3000 world.

Had a problem after corrupting the recent file list. Think it might have
happened when I deleted a file, outside of OpenCobolIDE, when it was
up-and-running.

I fired off an email to Colin Duquesnoy (the main author) about my problem,
went to bed (it was nearly 1 o'clock in the morning), and found a reply in my
inbox 1st thing the next morning. Was back up and coding by 8 o'clock.

Impressed by the product and the support response (a 7 hour turnaround for
FREE!!).

Would recommend it to anybody.

It is best to visit the LaunchPad cobcide parent pages for the latest source code, GNU/Linux packages and Windows installers at

https://launchpad.net/cobcide/+download

1.15.2   Geany

Geany is a light weight GTK based development environment and has surprisingly pleasant COBOL support. http://www.geany.org/

There are other IDEs that support COBOL. Google may respond with a list that suits taste.

1.16   Can GnuCOBOL be used for production applications?

Depends. GnuCOBOL is still in active development. Feature coverage is growing, and while the current implementation offers great coverage, applicability to any given situation would need to be analyzed, and risks evaluated, before commitment to production use.

The licensing allows for commercial use, but GnuCOBOL also ships with notice of indemnity, meaning that there are no guarantees when using GnuCOBOL, directly or indirectly.

And yes, GnuCOBOL is used in production environments.

See the chapter on GnuCOBOL in production for a growing list of details regarding GnuCOBOL in production environments.

From [Roger]:

Incidentally, OC has been (and still is) used in production
environments since 2005.
(This includes projects that I personally worked on plus other
  projects reported to me; these worldwide)

The OC project would not have been where it is today without the
significant/enormous help from many-many persons. The THANKS
file does not even do justice to this.

1.16.1   FAQ author’s take on it

If GnuCOBOL is going to break, it’s going to break right in front of you, during compiles. If something is not fully supported, GnuCOBOL fails very early on in the trial process. With most COBOL 85 and many nifty COBOL 2014 features, if cobc doesn’t complain during compiles, then GnuCOBOL is a very trustworthy and robust COBOL. If you work with newer features, beyond 1989 instrinics, there may be more reason to keep an eye on things. It would be due diligent to run comprehesive tests before committing to mandatory regulatory reporting systems or other life and core critical deployments. Be prepared to scan emitted C source codes. Know that GnuCOBOL is a free software system. Critical issues can be, are being, and will be addressed. No permission is required to try and make GnuCOBOL a better, more reliable system, and there is a host of very smart people willing to pitch a hand forwarding that goal.

1.16.2   Nagasaki Prefecture

Reported on opencobol.org, The Nagasaki Prefecture, population 1.44 million and 30,000 civil employees is using GnuCOBOL in support of its payroll management system. A team of 3 ported and maintain a suite of 200 COBOL programs, mingled with Perl and specialized reporting modules, running on Nec PX9000 big iron and Xeon servers.

1.16.3   Stories from Currey Adkins

Another post from opencobol.org in April 2009, reprinted with permission.

GnuCOBOL viability

For those concerned about the viability of OpenCOBOL in a production
environment, I offer our situation as an example.

We started loading OpenCOBOL to a Debian (Etch) Parisc box in mid March. With
some valuable help from this forum we were up and running in a few days.

We then explored the CGI capabilities and moved our home-brewed CGI handler
(written in HP3000 Cobol) over. We ended up changing only a few lines.

As Marcr's post indicates, we found a MySql wrapper and made some minor
changes to it.

Starting the second week in April we were in full development of new systems
for commercial use.

Please accept our congratulations to the community and our gratitude for the
help from the forum.

jimc

Another reference by Jim, some 6 months later in February 2010, which seems to be enough time for any rose-coloured glass effect to have worn off if it was going to.

For our part, the answer is yes.

You may want to read an earlier thread about this. Search on OpenCOBOL
viability.

Having worked with Cobol since the 1960's, my mindset is that no
conversion is automatic.

In our case we are not converting from a specific dialect like MF,
but instead are either writing entirely new systems or are changing
features (making them web based for example) in older systems.

There are some identified failures in OpenCOBOL execution that have
been discussed in this forum. We have found them to be inconsequential
and simply work around them. Then again I do not remember working with
a bug-free compiler.

Our environment is Debian Linux, OpenCOBOL 1.1, MySQL, ISAM (the one
provided with the 1.1 prerelease), HTML (via CGI) and a new PreProcessor
to relieve the tedium of writing SQL statements.

If you have some "nay sayers" in your organization and would like some
support I will be happy to speak with them.

jimc

I hope people don’t mind a little advertising in this FAQ, but Jim has done a lot for GnuCOBOL, and his company is a community minded company. http://curreyadkins.com/custom-programming-linux-php-apache-open-source/

1.16.4   Public Accounting

Another from opencobol.org

As part of an initial study of COBOL compilers for finding an alternative to
that of Micro Focus, OpenCobol was selected to develop a model for the
compilation of a public accounting package (1.5 million lines).

The model had to validate this choice, including with the use of sequential
indexed files, with OpenCobol version 0.33 and small adjustments to the COBOL
code (mainly using reserved keywords and keywords not implemented).

After the functional qualification of this model, the software is in production
since July, 2011 under Linux RedHat Enterprise Linux 4 Advanced Server 32-bit
virtualized environment VMWARE ESX – 4 GB of RAM - processor dual AMD Opteron
6176 (tm).

The software package is deployed for 650 users whose 150 connected
simultaneously, at the peaks of activity and in comparison with the previous
platform on AIX 4.3 and Micro Focus, performance gain is in a report, at best,
1-10 (batch of exploitation of entrustment), at worst, 1 to 4 (batch of
recalculation).

With the rise of the package version, a functional validation is in progress
since September 2011 with OpenCobol version 1.1 under Linux RedHat Enterprise
Linux 5 Advanced Server 64-bit and dual Quad-Core AMD Opteron 8356 (tm)
processor. No loss of performance related to the new version of OpenCobol (but
related to the package of 10% to 20% loss) after campaign in the two
environments.

1.16.5   ACAS

From Vincent Coen, also author of the CobXRef utility used by cobc -Xref.

Applewood Computers Accounting System.

If you wish you can also add the fact that the Account package ACAS has
also been migrated over to GOC and is used in productions for various
users. There is at least one more Accounting system called APAC that
has been migrated over from Micro Focus in the last year or so

I have also migrated both Mainframe Cobol applications to GOC running on
Unix, Linux & Sun variants based systems for companies and governments
in the UK and elsewhere including countries where English is not the
spoken language (but luckily the programming is generally in English or
similar) including languages which is written right to left.

Again luckily I did not have to convert/migrate the manuals.

As a guess I would say that over 2 million code lines have been migrated
at this time where the target compiler has been v1.1 and more lately
v2.0/v2.1.

1.16.6   A platform port

From SourceForge:

It is done. We used open Cobol to migrate old archive-Data from Z/os to
Unix/linux.  At the end of the year we stop working on Z/OS because all our
Data and Software is migrated to SAP and Linux/Unix. But there were many old
archive-Data files wich coudn't migrated to SAP. So our solution was to use
OpenCobol to do the Job. We also could do it with our IBM-Cobol-Compiler but
there is one problem. When the Z/OS is gone, you have no chance to repair any
mistake. So wie transferred all our archive-Data in binary sequential format to
Linux. Then, some open-Cobol-Programs convertet them from EBDCIC to ASCII -
cvs-Format. This was my idear because this is a format that every database and
so on can read and understand. So we use OpenCobol-Programs for converting and
formatting and may be siron, web oracle or what else to bring the data to the
enduser. The old data were sequential tape-files and VSAM-KSDS and the binary
files for trnansfer were createt by the sort-utility. The only thing was, to
remember to use binary mode for then transfer to linux and to keep the
record-information (PL/1 Copybooks, Cobol-Copies, SIRON-GENATS) also on the
linux-side. So the big trucks can come at the end of the year and carry away
the about 30 years so loved IBM Mainfraime. But i have my ownd S/370, the
machine i began my IT-Carrier. It is running under Hercules with MVS 3.8 and i
love it. As a hobby i wrote a Fullscreen-controled Horse-Management-System with
ifox00 (assembler) and Cobol68. I wrote some assembler-routines to bring the
dynamic call also to cobol 68 and it works so fine....
Real computing is a IBM Mainfraime. I love the real System-Console and so on...
When you ever worked with such a machine you know what it really means..
Mouting tapes, inserting paper in a line-printer, starting jobs with real
cards, all that i have done and it was the most fun with this old machines and
technics.

1.16.7   The COBJAPI angle

With László Erdős’s COBJAPI contribution, an entirely new way of programming COBOL has appeared. Rod Gobby was impressed enough to take on the task of porting his company software inventory to this new system.

So since 1977 I've gone from FORTRAN, to Assembler, to PL/I, to Business
BASIC, to MS-COBOL, to Power Basic, to GnuCOBOL. At each language change my
code generators have gained more features -- so now my non-OOP Power Basic
is generating OOP GnuCOBOL. The application specs have essentially remained
unchanged for 30 years, but the code looks a lot more sexy, now that I'm
back with COBOL. :-)

By the way, COBJAPI just keeps getting better. A simple event loop
integrates nicely with our GnuCOBOL classes, especially now that we seem to
have overcome some issues with ENTRY and CALL. ;-)

Rod

Another quote from Oscar on SourceForge

...
this is amazing what you can do with this compiler and now that java GUI
can be invoked using COBJAPI i feel so great.

See What is COBJAPI? for some details on this very powerful sub-system.

1.16.8   A thank-you note

From Gerhard on SourceForge, February 3rd, 2017:

I want to thank everyone for your help in getting me started in GnuCOBOL.
I was able to develop my first two COBOL programs from scratch. I used
several FUNCTIONs, built several multidimensional arrays, and called a C
program to return several values back to my program. These were the first
COBOL programs I've developed from scratch. I've done minor COBOL
maintenance in the past. We successfully implemented my two programs for
an ADP to Construction Management System interface at a company with over
20,000 employees. The project was a huge success and my team will use
these two programs as models for future development.

Thank you and Thank you again!!!

What more could a volunteer team ask for?

https://sourceforge.net/p/open-cobol/discussion/cobol/thread/dc356ed1/

1.16.9   Commercial Support

Although we’d rather that free COBOL is also fiscally free; anyone needing commercially backed technical support or development assistance can contact Open COBOL by the C Side. OCCSide Corporation.

Full disclosure: This author is a involved in the corporation, and we maintain a contact and project management space at http://occside.peoplecards.ca/

1.17   Where can I get more information about COBOL?

The COBOL FAQ by William M Klein is a great place to start.

A google of the search words “COBOL” or “GnuCOBOL” or “OpenCOBOL” are bound to lead to enough days worth of reading of in-depth articles, opinions and technical information to satisfy the greatest of curiosities.

Please ignore the “COBOL is dead” tone that many of these articles may be permeated with. COBOL isn’t dead, but it is usually used in domains that require the highest level of secrecy, so the billions of lines of production COBOL in use around the globe, rarely, if ever, get mentioned in internet chatter. Hopefully by reading through this document, and keeping an open eye on reality versus trends, you will see the importance that COBOL has held, does hold, and will hold in the computing and programming arena.

A new spec for COBOL 2014 was Published in May 2014 by Donald Nelson of ISO/IEC with adoption by ANSI in October 2014. Not dead, or dying or any such thing. With free COBOL, in GnuCOBOL, it’s still dancing.

As a side note, when the original specification was being written, one of the committee members, Howard Bromberg commissioned a tomestone, in 1960. Ignore the trend setter tones and look to the reality. http://www.computerhistory.org/fellowawards/hall/bios/Grace,Hopper/

This is highly subject to change, but a Draft of 2014 is/was available at http://www.cobolstandard.info/j4/index.htm and in particular http://www.cobolstandard.info/j4/files/std.zip

Note

While GnuCOBOL can be held to a high standard of quality and robustness, the authors do not claim it to be a “Standard Conforming” implementation of COBOL.

1.17.1   COBOL programming examples

For COBOL code samples, (aside from the listings included in this document, and with a much wider range of authoring style), the Rosetta Code website is a very good reference. See Rosetta Code for more information on this comprehensive programming language resource.

1.17.2   COBOL Programming Course

One of the preeminent COBOL learning resources on the internet, are the tutorials, example programs, COBOL programming exercises, lecture and other notes written for the Department of Computer Science and Information Systems of the University of Limerick, by Michael Coughlan.

http://www.csis.ul.ie/cobol/ for all the links, and

http://www.csis.ul.ie/cobol/course/Default.htm for most of the courseware links, but don’t miss out on the other pages linked on the “All Things COBOL” main page. These pages are over a decade old, and like all things COBOL, still very relevant at that young of an age.

1.17.3   Up and Running with COBOL

Hosted by Peggy Fisher, and Lynda.com, there is a very well done set of video tutorials available for getting Up and Running with COBOL. Peggy runs through setting up GnuCOBOL with Windows and Notepad++, and then follows up with

  • Describing Data
  • Control Structures
  • Sequential Files
  • Advanced Sequential Files
  • Direct Access files
  • Tables in COBOL
  • String Handling

Well spoken, well paced. About 50 videos, taking a little over 3 hours start to finish.

Recommended for anyone wanted to get setup with GnuCOBOL on Windows, and a recommended share to anyone looking to get into COBOL programming in general.

Peggy touches on mainframe issues when discussing some COBOL issues, so this is a fairly solid start for anyone interested in COBOL programming.

There is a scrolling transcript that keeps pace with the dialogue, and these are professional grade vidoes.

https://www.lynda.com/COBOL-tutorials/Up-Running-COBOL/411377-2.html

1.17.4   jaymoseley.com

Jay Moseley has written up quite a few COBOL related tutorials, and has added a lot to the world of the Hercules System/390 emulator. He dug in and wrote up bootstrapping instructions for old MVS releases so people can experiment with versions of big iron operating systems on home computers. Including getting a public domain copy of a 1972 version of IBM ANS COBOL up and running.

See Hercules for more details.

Jay has also added a GnuCOBOL page to his large mix of information pages.

http://jaymoseley.com/gnucobol/index.html

You’ll find sample programs for parsing CSV, displaying the number of days between dates, and lots more.

See REPORT for a very complete sample and introduction to using the ReportWriter features that are available in the reportwriter branch of the GnuCOBOL source tree.

1.17.5   tutorialspoint.com

There is an online learning centre, tutorialspoint.com Simply Easy Learning, and they have posted courseware for COBOL, JCL, and many other topics.

Before reading any further, note this critique, from Bill Woodger (July, 2015):

Mmmm... to me the tutuorialspoint stuff is pretty shoddy. To imply that
you need Hercules to run COBOL is... let's say, quaint. On top of that
they seem to imply that a Hercules user would use z/OS. z/OS is a
licensed product, and IBM will not, full-stop and no questions, license
it for Hercules.

I think I've yet to see a page from there that I didn't dislike, because
it will confuse, mislead or plain lie to a new user of COBOL, through
omission and commission.

I think the Cork stuff is orders of magnitude more useful to someone
starting out with COBOL.

I do not think tutorialspoint should be linked-to from the GnuCOBOL
Project.  We can obviously discuss this further, If necessary, I can
come up with an "oh, no, I don't like the look of that" for, say, each
of 20 pages.

As you can tell, I disagree with not pointing out the tutorialspoint tutorial, but you will likely be much better off starting with Micheal Coughlan’s CSIS tutorials, listed above.

The COBOL course includes source listings with a Try It button, OpenCOBOL used in the background to run compiles and display results to the web forms. (Once GnuCOBOL 2.0 makes its way into the main free software distribution repositories, they will very likely upgrade to the latest builds)

They also include instructions for setting up Hercules, a System/370 emulator, and include IBM MVS samples, including JCL listings to launch UCOB compiles. The Hercules samples are “at home only” and have not been linked to the web form Try It buttons. Any COBOL tried online will be passed through a GnuCOBOL compiler, and will, by neccesity, only work with sources supported by GnuCOBOL (or more accurately, OpenCOBOL pre-release 1.1).

http://www.tutorialspoint.com/cobol/index.htm

1.17.6   newcobug.com

After the passing of Thomas Perry in 2014, cobug.com went off the air. It is archived in the Wayback Machine, and those pages became the starting point for Robert Skolnick’s new newcobug.com site.

https://web.archive.org/web/20140108215107/http://www.cobug.com/cobol.html

cobug.com was for many years, a go to place for all things COBOL related, in particular a vendor agnostic, but still commercially oriented set of COBOL pages.

Robert will be trying to ensure the continuity of the site, and modernizing it along the way, at http://newcobug.com. He has even gone as far as adding a subdomain, (which we have not yet taken full advantage of), for GnuCOBOL related COBOL issues. http://gnucobol.newcobug.com. Robert, being involved with a large internet service provider in Brazil, is well versed in all things internet, and newcobug.com has a very good chance of becoming the new cobug.com.

1.18   Where can I get more information about GnuCOBOL?

Current project activities are at SourceForge.

The discussions on the opencobol.org website permanently redirected to SourceForge, have been archived at http://open-cobol.sourceforge.net/files/opencobol.org-archive.tar.gz (2Mb) and as plain text at http://open-cobol.sourceforge.net/files/opencobol.org-archive.txt (8Mb).

add1tocobol.com is a place to find out about a few of the fan initiatives. (An older website is readonly at http://oldsite.add1tocobol.com)

1.18.1   The GnuCOBOL Programmer’s Guide

A very well written and masterful OpenCOBOL reference and COBOL development guide. By Gary Cutler, GnuCOBOL Programmers Guide.

1.18.2   The OpenCobol Programmer’s Guide

Is still available, at OpenCOBOL Programmers Guide.

1.19   Can I help out with the GnuCOBOL project?

Absolutely. Visit the SourceForge project space and either post a message asking what needs to be done, or perhaps join the development mailing list to find out the current state of development. See Is there a GnuCOBOL mailing list? for some details. GnuCOBOL is an official GNU, GPL licensed, free software project, with a small team that handles the read/write permissions on SourceForge. The project is very open to code submissions. Having this central point of development allows for the consistency and the very high level of quality control enjoyed by GnuCOBOL users.

1.19.1   Contribution Guidelines

First to clarify a little bit. The GnuCOBOL “project” has two parts. The official GnuCOBOL compiler source tree, and external free software contributions, currently held in a source tree named contrib. Ok three parts; from the point of view of the “project”, we will gladly reference free software, commentary, and other free resources related to GnuCOBOL and COBOL by simple request or notice from authors. The keyword is free, freedom free. In term of the “project”, free COBOL is the main theme. Terminology wise, the “project” encompasses more than the GnuCOBOL project, a name normally associated with the official source tree, but being only a small part of the big picture.

Officially, GnuCOBOL is a GNU project, so we will abide by the rules and recommendations provided by this very successful free software foundation. Write access to the sources is restricted to those that have signed legal copyright transfer documents, noted below.

GnuCOBOL is also a COBOL project. Not all contributions are part of the legally copyrighted GnuCOBOL sources, owned by the Free Software Foundation, Inc. Be that code, documentation, or other media. Contributions can be made under other forms and licensing, and they are addressed separately. No blocks will be put in place of anyone wanting to help, aside from the overriding concerns that pay homage to the principles of free software.

The GNU recommendations can be found at http://www.gnu.org/prep/standards/standards.html which includes

If the program you are working on is copyrighted by the Free Software
Foundation, then when someone else sends you a piece of code to add to the
program, we need legal papers to use it—just as we asked you to sign papers
initially. Each person who makes a nontrivial contribution to a program must
sign some sort of legal papers in order for us to have clear title to the
program; the main author alone is not enough.

So, before adding in any contributions from other people, please tell us, so we
can arrange to get the papers. Then wait until we tell you that we have
received the signed papers, before you actually use the contribution.

This applies both before you release the program and afterward. If you receive
diffs to fix a bug, and they make significant changes, we need legal papers for
that change.

This also applies to comments and documentation files. For copyright law,
comments and code are just text. Copyright applies to all kinds of text, so we
need legal papers for all kinds.

There is more commentary on the need for the inconvenience and a lot more in the GNU Coding Standards, , but again, the “project” is more than the compiler project.

That’s GNU, and contributions to the GnuCOBOL source tree. Contributions outside that tree are also welcome, as long they count as free software.

GnuCOBOL adds, from the project lead, Simon Sobisch, human;

Entries MUST be L/GPL. That's Lesser General Public License and/or General
Public Licence.

Authors MUST be willing to hand copyright over to the FSF.

COBOL source modules MUST compile warning/error free, with options

1. -W
2. with any of the standard "-std=" options.
3. with either option -fixed(default) or -free
4. Any/all combination of above

Further these COBOL modules MUST execute correctly however they have been
compiled (-std=).

The rule for project approved samples can be seen as:

Should work. Preferable they compile warning free with -Wall (not have to).
Reference format doesn't matter. If it doesn't work with some configurations
(or better: need a specific configuration) this has to be documented.

And that’s for code.

Full disclosure: I’ve been writing samples for this FAQ that usually compile warning free with -W by adding scope terminators with END-DISPLAY, END-ACCEPT, END-COMPUTE etc. I thought approved samples followed the MUST rule.

It has been pointed out that a few of these scope terminators aren’t just more typing, they also clutter long understood source code constructs when there are no conditional imperatives such as ON EXCEPTION.

DOH! 2008 through 2015. I don’t really want to count how many hours have been spent typing END-DISPLAY into code examples. As of Oct 2015, there will be less of those.

Other contributions include cheerleading, bug reports, discussions, notice of free COBOL that works with the compiler, or should, but needs porting, etc.

And a big one, which will require signatures for reassignment, internationalization and translations.

1.19.2   Translation Efforts

A new project has started to see native language support in the cobc compiler and run-time systems. Skip ahead a little to see the links for the new efforts. What follows in hitorical information, just for completeness.

From Simon, some many moons ago, when he went by the nickname human.

Subject: OC in your native language - translators needed

Hi folks!

We’re starting to translate upcoming versions into different languages. The necessary code changes for OC 2.0 were already done. Now we need translators.

Before posting every stuff here I want to gather the translators here. Who is able and willing to translate the strings (currently 724) into what language(s) [or has somebody who does this]?

From the last discussions I remember people wanting to do this for French, Italian, Spanish, German but I don’t remember who exactly said that he/she will help. We already have a Japanese translation, but that needs an heavy update.

Later edit

For a new translation create a new catalogue from the pot file. I encourage everybody to use a GUI for that. Some explanations how to do that with my favourite language file editor [url=http://www.poedit.net/]Poedit[/url] and some general instructions:

Some hints for Poedit first-time-users:

  • Choose the string you want to translate in the upper pane.
  • Translate the text in the lower pane.
  • Always keep special characters like %s, %d, n, ... The % are place holders (values will be inserted there by OpenCOBOL). n is a line break, t a tab, etc
  • Use [ALT]+[C] often. It copies the original string to the translation field where you can change what’s needed. This function can be found in edit menu, too.
  • If you’re not sure if one of the translations is correct mark it as fuzzy with [ALT]+[U] or via edit menu.

Current assignments of translations: fr: eraso (finished [updates will be needed later]) [earlier: Bear (maybe aouizerate, too)] hi: Yanni de: erstazi es: jcurrey (finished [updates will be needed later]) ja: minemaz (later) it: ?federico?

OK, here is the http://www.filedropper.com/open-cobol]pot-file from 11-09-06.

human

Update: March 2015

The GnuCOBOL translation effort will be included in an official translation project. Thanks to the many volunteers there. From Simon:

http://translationproject.org/

Hi folks!

We're starting to translate upcoming versions into different
languages. The necessary code changes for OC 2.0 were already done.
Now we need translators.

Before posting every stuff here I want to gather the translators
here. Who is able and willing to translate the strings (currently 667)
into what language(s)
[or has somebody who does this]?

From the last discussions I remember people wanting to do this for
French, Italian, Spanish, German but I don't remember who exactly said
that he/she will help. We already have a Japanese translation, but
that needs an heavy update.

...

Later:

GnuCOBOL 2.0 includes support for English, Spanish and Japanese
messages, errors and warnings.  Source portable object .po files
are nearly complete for Dutch, French and German.  Italian can't
be too far off.

Activity will take place on http://translationproject.org

To try Spanish messaging, see Setting Locale, basically export LC_MESSAGES=es_ES before calling the compiler.

And please note that these translations are only the compiler and libcob run-time messages, not COBOL syntax or reserved word spellings in source code. COBOL is, by specification, an English programming language.

1.20   Is there a GnuCOBOL mailing list?

Yes. The GnuCOBOL development mailing list is graciously hosted by SourceForge. The ML archive is available at http://sourceforge.net/p/open-cobol/mailman/open-cobol-list/ and once you have subscribed, the list will accept messages at the open-cobol-list email destination at lists.sourceforge.net.

1.21   Where can I find more information about COBOL standards?

The COBOL 85 standard is documented in

  • ANSI X3.23-1985
  • ISO 1989-1985
  • ANSI X3.23a-1989
  • ANSI X3.23b-1993

This is highly subject to change, but a Draft of COBOL 2014 is/was available at http://www.cobolstandard.info/j4/index.htm and in particular http://www.cobolstandard.info/j4/files/std.zip

In May 2014, the new specification for COBOL 2014 was Published by ISO/IEC. The document was approved in early summer, and adopted by ANSI in Octber, 2014.

Note

While GnuCOBOL can be held to a high standard of quality and robustness, the authors do not claim it to be a “Standard Conforming” implementation of COBOL.

1.22   Can I see the GnuCOBOL source codes?

Absolutely. Being a free software system, all sources that are used to build the compiler are available and free.

Visit http://sourceforge.net/p/open-cobol/code/HEAD/tree/ to browse the current SVN repository.

The SourceForge Files section has links to older release and pre-release archives.

Most distributions of GNU/Linux will also have source code bundles. For example

$ apt-get source open-cobol

on Debian GNU/Linux will retrieve the most recent released package sources.

1.22.1   A ROBODoc experiment

A ROBODoc experimental project to document the source codes is hosted at ocrobo. See ROBODoc Support for a sample configuration file.

The ROBODoc homepage is at http://rfsber.home.xs4all.nl/Robo/robodoc.html.

Frans accepted changes to the main ROBODoc source tree, hosted at https://github.com/gumpu/ROBODoc to be more friendly with COBOL sourcecode, dashes in names being the biggest change.

Downloads of versions beyond 4.99.42 of ROBODoc will be COBOL friendly when passed the --cobol command line option. ROBODoc is in the Fedora package repos and work is in progress to have this package re-included in Debian repositories.

1.22.2   A Doxygen pass across the compiler source code

This is mentioned elsewhere, but the GnuCOBOL compiler source code bundle works beautifully with Doxygen. Mix application and compiler sources for overwhelmingly complete call graphs.

Is there GnuCOBOL API documentation?

Dimitri van Heesch’s 1.7.4 release of Doxygen, http://www.doxygen.org was used to produce http://opencobol.add1tocobol.com/doxy/.

1.22.3   A Doxygen pass, application with compiler suite

Along with Gary’s OCic.cbl http://opencobol.add1tocobol.com/doxyapp/ to demonstrate how easy it is to generate world class, audit friendly source code documentation, drilled right down to how the COBOL run-time is interacting with the operating system.

1.22.4   What was used to colour the source code listings?

I wrote a Pygments lexer, mushed it into a local copy of Pygments and then call a rst2html-pygments.py program. Requires a fair amount of mucking about. See ReStructuredText and Pygments for some details.

As of January 2013, the COBOL lexer is in mainline Pygments. No more mucking about required. Georg Brandl did a wonderful job of refactoring the COBOL highlighter into his Pygments system. Many thanks to Georg, Tim and team Pocoo.

https://bitbucket.org/birkenfeld/pygments-main/pull-request/72/adding-an-opencobol-lexer

This is now included on SourceForge. In the discussion groups, source code can be highlighted using SourceForge markup. A blank line, a line starting with six tildes, another line starting with two colons, followed by a language tag. Many, available, but for fixed form COBOL use cobol, for less indented, free form COBOL, use cobolfree. Then code, then six closing tildes.

As an example; here is a SourceForge message with a code block.  Blank line
before the tildes counts, otherwise it isn't seen as a code block paragraph.
Sadly, spaces in a visually blank line can confuse the start of paragraph
detection.  If it looks like highlighting should be working, and isn't,
backspace over the preceding line, just in case.

~~~~~~
::cobol
 SAMPLE
       * Next big thing
        IDENTIFICATION DIVISION.
        PROGRAM-ID. big-thing-42.
        PROCEDURE DIVISION.
        DISPLAY "ok, what now?"
        GOBACK.
~~~~~~
then more message, (and the message part doesn't need the blank line after
the closing tildes, as the closers inform the markup of what's what).

~~~~~~
::cobolfree
    PERFORM 3 TIMES
        DISPLAY "Yeah, that!"
    END-PERFORM
~~~~~~

and more message, which can have a preceding blank line.

Otherwise, to get the forge to highlight code, indent the block by four
spaces.  The tildes can be more convient for COBOL listings though,
as it can save moving text around, inside the browser edit widget.

Giving:

SAMPLE
      * Next big thing
       IDENTIFICATION DIVISION.
       PROGRAM-ID. big-thing-42.
       PROCEDURE DIVISION.
       DISPLAY "ok, what now?"
       GOBACK.

and

PERFORM 3 TIMES
    DISPLAY "Yeah, that!"
END-PERFORM

This is a context free regular expression colourizer. It gets true COBOL wrong, but mostly right, for the benefit of colour.

Initial indentation counts. Code starting with column 8 followed by a comment in column 7 can confuse the indentation detection. That can be fixed by adding a sequence number tag in columns 1 through 6 to the first line of code in the listing.

1.23   What happened to opencobol.org?

Due to robot spam, new registrations on opencobol.org were disabled in 2012.

The active site is now hosted by SourceForge, at

http://sourceforge.net/projects/open-cobol/

In case anyone is wondering, as of May 2014, 1 (one) entry has shown up in the spam folder and required moderation. Thanks, SourceForge; frees up many hours of volunteer time. Many. There was spam in the reviews, well, hit count hounds, and even those seem to be dealt with, quietly in the background. Nice.

opencobol.org was redirected to the SourceForge site in October of 2015. There is an archive of the forum posts, and knowledge base, stashed away at

http://open-cobol.sourceforge.net/files/opencobol.org-archive.txt

which is about 8 megabytes of text. Sadly this archive does not include all the metadata (author, and timestamps) that were included with the forum entries, but is still a treasure trove of GnuCOBOL related technical wisdoms.

1.24   What is COBOL in Latin?

I came up with Publicus Negotiatio Cursus Lingua, and then smarter people suggested:

  • negotium orientatur lingua plebeius
  • generalis negotium pertineo lingua
  • de communi codice pro calculorum negotii
  • codex communis pro calculorum negotii

I like the last one. ccpcn, pronounce that as kick-pickin’.

Thanks to Ray, Paul, and Daniel on LinkedIn.

1.25   Where can I find open COBOL source code?

Although open source COBOL is still rare, and free even rarer, that is slowly changing. This entry will be a perpetually growing list, until the universe is at peace.

\begin{flalign*}&\lim_{\textsc{cobol}\to\infty}f(\textsc{cobol}) = 42^{42}\end{flalign*}

Last updated: June 11th, 2013. If you know of a worthy entry, drop me a note.

1.25.2   on SourceForge

GnuCOBOL is hosted on SourceForge at http://sourceforge.net/projects/open-cobol/

Other projects include:

1.25.3   add1tocobol

The good folk that host this FAQ, also host http://oldsite.add1tocobol.com and http://add1tocobol.com

1.25.4   Stickleback

Wim Niemans’ Project Stickleback, http://stickleback.nlbox.com/

1.25.5   other places

1.26   What is bubble-generator?

Or, where did the GnuCOBOL syntax diagrams come from?

Dr. Richard Hipp created a small set of Tcl/Tk scripts to assist in drawing syntax diagrams for SQLite. These public domain scripts were modified slightly to create the syntax diagrams used in the GnuCOBOL FAQ, as bubble-cobol.tcl and bubble-cobol-data.tcl. In keeping with the spirit set by Dr. Hipp, the syntax diagrams in this document are also dedicated to the public domain.

Sourced from the SQLite repository, and discovered at http://wiki.tcl.tk/21708. In this author’s opinion, true to Richard’s other works, these scripts produce beautiful diagrams. Tcl/Tk is used to produce Postscript outputs, which are then further processed by ImageMagick to produce the final .gif and .png images.

Extra font control was added, and in the GnuCOBOL FAQ version of the syntax diagrams, a non-bold font is used to denote GnuCOBOL extensions that are not part of the COBOL 2014 specification. Or at least, attempts were made to do so. GnuCOBOL does not claim any level of conformance to standard, and the syntax diagrams in this document are not indicative of COBOL syntax as defined by ISO and/or ANSI.

Although subject to change and correction, the sources used are listed here under bubble-cobol.tcl.

1.28   Tutorial

Getting started with GnuCOBOL. This section assumes a GNU/Linux install, but much of the COBOL material is platform agnostic. Command examples will be shown using bash inside a terminal console.

Attention

COBOL is a big programming language. There are thousands of details. This tutorial will gloss over many issues in order to try and focus on one or two key points without overwhelming the reader.

1.28.1   Working directory

For this tutorial, you will need a working directory to store source code, executables and data files. I use:

cd ~/lang/cobol/

A subdirectory in my login home, called lang/cobol. You are free to choose your own working directory. All you need to remember is that you need to remember where it is, so when you come back to the computer after a break you’ll be able to find your work.

Go ahead and create the directory, and/or change into it. For example:

cd $HOME
mkdir gcfaq/tutorial
cd gcfaq/tutorial

You can use that name, gcfaq/tutorial, if you like, but it is much better to pick your own easy to remember favourite. No one will be able to remind you, as it is a personal choice, so pick one you like and that you will be able to remember a few months from now if you ever need to come back for a refresher.

1.28.2   Hello

We will start with Hello. Of the four main COBOL divisions, this introductory sample only includes IDENTIFICATION and PROCEDURE. There are a few comment lines, some COBOL “paperwork” phrases and only two executable statements. We’ll compile and run the program as part of the exercise.

Fire up your favourite editor and type the following into a file called hello.cob. (That filename is the name that will be used throughout the rest of this tutorial, so if you pick a different name this time, you are on your own to remember what it is, and to change each of the commands to suit).

      *>
      *> hello.cob, GnuCOBOL FAQ tutorial
      *>
       identification division.
       program-id. hello.

       procedure division.
       display "Hello, world"
       goback.

       end program hello.

tutorial/hello.cob

There is a handy download link for that source code if you are browsing this on the web, but as a COBOL developer, you need to get used to typing. So learn some COBOL the hard way and start typing. I use vim, but you will want to use a text editor you are comfortable with. Text editing is tool of the trade that you need to be comfortable using, and there are literally hundreds of choices.

Once you have that source code in a file called hello.cob, inside your working directory, the real fun begins.

1.28.3   Compiling hello

This is where cobc comes in. cobc is the GnuCOBOL compiler front end command. It does a lot of nifty things, but for now we will focus on compiling and running this simple program.

From the command prompt, type:

cobc -x hello.cob

This starts the compiler and asks cobc to generate an executable program.

Example compile:

prompt$ cobc -x hello.cob

The -x switch is what tells cobc to create the executable file. cobc can generate other forms of output, but we want a runnable program at the moment.

If there are no syntax errors then you should now have another file in your working directory, called hello. It will have modes and permissions already set for you to to be allowed to run the program.

Now type:

./hello

That command will start the new hello program from the current working directory. The system will not bother searching through the command path to find it. hello is the program, and the ./ part is a short form directory specification meaning from here, in the current directory.

Example run:

prompt$ ./hello
Hello, world

And there is your introductory COBOL program with GnuCOBOL.

The purpose of Hello, world programs is to verify that the system is installed to a minimum functioning level. The message on the screen tells the operator that the compiler worked, and the run time system can at least do basic output.

It might seem trivial, but the validation means that a lot of things in the background are properly working. A lot. Really, a huge number of things have to be properly setup for that simple message to be displayed on screen.

If it didn’t work, then you have Gary’s Programmer’s Guide and this document to help you with trouble shooting. There is also an awesome forum on SourceForge, ready and willing to answer any questions you may have regarding Help getting started at https://sourceforge.net/p/open-cobol/discussion/help/.

Attention

A short note about Windows. On Windows, without a reasonable console, what will happen is that invoking the program will start a console, display the message and then immediately close the console. All you may see is a flicker. More recent versions of GnuCOBOL now include a default exit handler that will pause the console shutdown, giving you a chance to see the output. Versions of GnuCOBOL older than 2.0-rc3 will not have this feature.

1.28.4   Line by line

Let’s go over hello.cob one more time. This time, from a full listing that is available in the downloadable copy.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
GCOBOL*>-<*                                                             
      *> Author: Brian Tiffin
      *> Dedicated to the public domain
      *>
      *> Date started: January 2017
      *> Modified: 2017-02-02/17:22-0500 btiffin
      *>
      *> Tectonics:
      *>   cobc -x hello.cob
      *>   ./hello
      *>+<*
      *>
      *> hello.cob, GnuCOBOL FAQ tutorial
      *>
       identification division.
       program-id. hello.

       procedure division.
       display "Hello, world"
       goback.

       end program hello.

The first 14 lines are comment lines, they introduce the purpose of the program, show some dates, the usage rights and include some hints on how to build from source and how to run the program. I call that last part the tectonics.

Hopefully all your programs come with this minimal level of preamble. Even if you never share a program, it is nice to be able to just glance at a header to see how to properly build and run a program. This is as simple as it gets, programs only get more complicated from here.

The comment indicator used for GnuCOBOL is *>, and this tells the compiler to ignore the rest of the text, up to the end of the line.

Next up is the first actual instruction to the compiler, line 15, the IDENTIFICATION DIVISION statement (which ends with a full stop period). This lets the COBOL lexical parser know that a new program definitions is starting. Mandatory with every program or nested sub-program. (That’s not entirely true, but true enough for an introductory tutorial).

I sometimes refer to these types of COBOL instructions as “paperwork” or “housekeeping”. These statements do not actually do anything in terms of run time effect, but they do influence how the compiler sets things up and organizes the technical details.

The next line is the PROGRAM-ID. statement, followed by a user defined program name. Both end with full stop periods. The name must follow a few technical rules, both to satisfy COBOL naming conventions and to satisfy operating system linkage rules. The operating system has to know how to find the program name when linking with other code, and COBOL can’t let you put things periods in the name. The literal hello is fine for both of these restrictions. This is more COBOL “paperwork”.

Then we get to the PROCEDURE DIVISION (and full stop) on line 18. This is another trigger phrase to tell the COBOL compiler that executable code follows. A little more paperwork.

Then we finally get to the first actual executable instruction on line 19. A DISPLAY statement, which is followed by a quoted literal message "Hello, world". There could be a period following this statement, but it isn’t mandatory. Sequential lists of statements form a COBOL “sentence”, and this example program is a single sentence, with two statements. All the previous lines of source code are paperwork statements (and comments). This is the first line of code that actually does something when we run the program.

COBOL does not get its reputation for being verbose from lack of trying. As you continue learning COBOL you will find that all these housekeeping instructions are actually a good thing. It keeps code organized and also enforces a minimum level of discipline when developing programs. These factors become much more important once programs grow larger than simple introductory examples.

The next statement is GOBACK. This keyword tells the compiler to generate code to return to the caller. Seeing as this is a main program, that means the return goes all the way back to the operating system. A status code is implicitly set by default, in this case a success code of 0. You rarely have to worry about COBOL setting a proper status code. It is a built in convenience feature. The GOBACK is terminated with a full stop period, the end of the one (and only) executable sentence in this program.

That one sentence contains two statements, DISPLAY literal and GOBACK.

The last line is end program hello. (terminated with a period). This is optional with this particular program, and is another housekeeping phrase. The identifying program name has to match the program-id. It tells the compiler that this program unit is complete. Later we will see that this is important (and becomes mandatory) when a source file contains more than one program unit.

That ends the initial quick tour of a Hello, world program in GnuCOBOL.

With GnuCOBOL being quite flexible, this program could be written in a wide variety of ways, all with the same outcome. We will see different forms of programs that produce equivalent outcomes later on in the tutorial.

Skipping ahead a little: GnuCOBOL is actually quite a sophisticated COBOL compiler, and it can make assumptions about some of the paperwork instructions. All of that typing can be condensed down to a simple

        DISPLAY "Hello, world".

tutorial/hello-oneliner.cob

Even though that looks much simpler, it is actually fairly advanced COBOL. You need to know the first version for this one liner version to really make any sense. To compile the short version, we need to tell the compiler to relax some of the normal COBOL syntax rules.

prompt$ cobc -x -frelax-syntax hello-oneliner.cob
hello-oneliner.cob: 1: warning: PROGRAM-ID header missing - assumed
hello-oneliner.cob: 1: warning: PROCEDURE DIVISION header missing - assumed

The outcome is the same, but the path getting there is a little different, and this time cobc emitted some warnings about some assumptions being made.

prompt$ ./hello-oneliner
Hello, world

As promised above, there will be other examples of Hello, world programs that look totally different in the pages ahead. COBOL is a very flexible programming language.

For the time being, forget that you saw that short-cut version of Hello. To learn COBOL you need to understand the paperwork phrases. They are important. Think of it as learning how to walk before starting to run. We all want to hop, skip and jump, but first we need to practise walking (after putting in some time crawling, which is hard on the knees, but we all start out that way).

1.28.5   The DIVISIONS

COBOL programs have four major DIVISIONS.

  • IDENTIFICATION DIVISION.
  • ENVIRONMENT DIVISION.
  • DATA DIVISION.
  • PROCEDURE DIVISION.

Each DIVISION is broken down into SECTIONS, PARAGRAPHS and SENTENCES. Sentences are broken down into STATEMENTS. Statements are made up of RESERVED WORDS, literals and variable identifiers. Paragraphs and sections have labels. Each of these fragments is terminated by a full stop period, much like in English.

In the hello.cob example, we only needed two DIVISION entries. IDENTIFICATION and PROCEDURE. That is a very rare case for COBOL programming. Anything that does useful work will have a DATA DIVISION. Anything that touches on external resources (usually data files on disk) will include the ENVIRONMENT DIVISION.

The order of the divisions is important. They must be entered in the same order as the list above.

IDENTIFICATION, ENVIRONMENT, DATA, PROCEDURE. GnuCOBOL will complain (COBOL will complain) if you try and put the PROCEDURE DIVISION before the DATA DIVISION, or mix up the order in any way. A handy mnemonic when starting out:

I Enter Data Properly

Entire DIVISIONS can be excluded (rarely), but when included, they must be in the proper order.

Let’s see what happens if the hello.cob source code is out of order:

      *>
      *> hello-wrong-order.cob, GnuCOBOL FAQ tutorial error example
      *> This program will NOT compile properly, divisions out of order
      *>
       procedure division.
       display "Hello, world"
       goback.

       identification division.
       program-id. hello-wrong.

       end program hello-wrong.

tutorial/hello-wrong-order.cob

You can skip typing that one in, it has bugs in it.

That code won’t compile, and cobc will complain:

prompt$ cobc -x hello-wrong-order.cob
hello-wrong-order.cob: 15: error: PROGRAM-ID header missing

Do yourself the favour and just repeat:

I Enter Data Properly
I E D P

IDENTIFICATION
ENVIRONMENT
DATA
PROCEDURE

1.28.6   Full stop, periods

Attention

A side trip, an important one. The period, ., also known as full stop, is an important character in COBOL. It terminates labels, sentences, paragraphs, sections, and a few other critical pieces of COBOL syntax.

Let’s see what happens if we forget a period in one of the critical spots. This version of hello.cob is missing the full stop after the IDENTIFICATION DIVISION sentence.

Don’t bother typing this one in either, it has different bugs in it.

      *>
      *> hello-missing-period.cob, GnuCOBOL FAQ tutorial error
      *> This program will NOT compile, missing a full stop after
      *>  IDENTIFICATION DIVISION
      *>
       identification division
       program-id. hello-missing.

       procedure division.
       display "Hello, world"
       goback.

       end program hello-missing.

tutorial/hello-missing-period.cob

That code won’t compile, and cobc will complain again:

prompt$ cobc -x hello-missing-period.cob
hello-missing-period.cob: 17: error: syntax error, unexpected PROGRAM-ID, expecting .

You need to worry about full stops in COBOL, and later on we’ll see how they can effect the interpretation of the instructions in the PROCEDURE DIVISION in weird and wonderful ways.

A small piece of advice is to use the minimum number of full stops to satisfy the rules of COBOL syntax. No more, no less. For now, just know that the period character is an important symbol in COBOL. It terminates a unit of text to let the compiler know when and how to compile source code. Before you know it, it will all make sense and you’ll be a master of the COBOL full stop.

1.28.7   Including Data

Almost all useful programs need to keep track of and manipulate data. Data forms the variable part of the code/data programming duality.

COBOL has a very rigid and technically detailed view of data. Unlike many programming languages, COBOL has a separate division for describing data layouts. Data definitions are not intermingled with code as they are in many other programming environments. This feature is a blessing. It forces a minimum level of discipline when programming. You need to think about, and plan, a COBOL program.

Back to the attention box at the start of the tutorial; in order to avoid overwhelming a beginner, there are many details left out in these initial exercises. The details will be touched on later. In particular, COBOL is very well suited for defining very complex record structures, but that has to wait.

1.28.8   Characters and numbers

COBOL is designed to help business people solve business problems. Data definitions in COBOL are designed for people to easily reason about the problem at hand. Definitions are rigid, and explicitly sized by PICTURE.

A PICTURE, shortened to PIC, is a human readable view of computer data. And there are two main types, character and number.

And numbers in this case are not for the benefit of the computer, they are defined for the benefit of the human reader. As it turns out, computers have a different natural view of numeric values than us humans. Computer don’t have ten fingers to count on, they only have on/off. We all grow up using a base 10 (decimal) assumption about what numbers mean, and COBOL is designed with that fact in mind. Computer grow up with a base 2 (binary) assumption. The designers of COBOL decided that compiler writers should do all the nitty-gritty hard work of converting numbers from human form to machine form, and let business people think and reason about problems using dollars and cents in a human natural decimal format.

Most other programming languages cater to the computer chip point of view of numeric values. COBOL is rare in this design feature, using decimal arithmetic by default.

01 CUSTOMER-NAME        PIC X(40).
01 ITEMS-PURCHASED      PIC 999999.

An X is a place holder for any character, and a 9 is a placeholder for any digit, 0-9 inclusive. You can’t do math with a customer name, and you can’t stick random characters in a numeric field.

Our next program is going to manage some data. It includes a DATA DIVISION. Inside the DATA DIVISION is the omnipresent WORKING-STORAGE SECTION. The WORKING-STORAGE SECTION is a mainstay of COBOL data storage. It implies that somewhere in the computer’s memory banks there is space reserved for the data. During any particular run it will remain fixed in place, ready for retrieval and/or manipulation, the working store.

This next program also introduces more COBOL verbs, MOVE and COMPUTE.

COMPUTE is a verb that tells the compiler to evaluate an arithmetic expression and put the result in a variable.

MOVE is a work horse data movement verb. It does more than simply move data from place to place, it also has rules about the type of the data movement, given both the source and the destination descriptions. More on that soon.

For this example, quoted character literals are moved into a message area for display. The messages could have simply been literals used with the DISPLAY verb, but for this example the messages are moved into a variable first, and displayed from there.

      *>
      *> simple-data.cob, GnuCOBOL FAQ tutorial
      *>
       identification division.
       program-id. simple-data.

       data division.
       working-storage section.
       01 program-message      PIC X(64).
       01 answer               PIC 99.

       procedure division.

       move "simple-data.cob example" to program-message
       display program-message

       move "compute 6 times 7" to program-message
       display program-message

       move "answer is:" to program-message
       display program-message

       compute answer = 6 * 7.
       display answer

       goback.
       end program simple-data.

tutorial/simple-data.cob

Fire up the text editor, in your working directory, and type that code into a file called simple-data.cob. Or, click the download link and save the file to your working directory.

Once again, a COBOL programmer cannot be afraid of typing, it is part and parcel of the job, so it is recommended that you struggle to type that in. Spacing counts. COBOL harkens back to a day before modern computer screens, and source text was entered on physical punch cards. Those days are long behind us, but the format used in this example (called FORMAT FIXED) needs to be properly spaced. Soon, we’ll use an updated feature of COBOL so that we won’t have to worry about the indentation as much, but for this example, the format is FIXED, code lines start in column 8, and the asterisks that start a comment have to be in column 7.

Note

On typing. COBOL programmers are famous for type it once, then copy and change it. There is actually quite a bit of paperwork in the average COBOL program.

See Do you have a reasonable source code skeleton for GnuCOBOL? for a handy example of this. But keep in mind that you need to practice walking before running ahead to the hop, skip and jump phase.

While you type in these examples you are building up your own personal collection of code templates that can be used later to quick start a project.

1.28.8.1   run job

This time, we will use a feature of cobc that compiles the program and then runs it, all in one step. The -j switch is a mnemonic for job. Along with -x it means, compile this code to executable and then run the job for me.

prompt$ cobc -x -j simple-data.cob
simple-data.cob example                                         
compute 6 times 7                                               
answer is:                                                      
42

If there are no errors, then you are now rewarded with the answer to the ultimate question about the meaning of life, the universe, and everything.

Your working directory will now also have a new executable program file, simple-data, ready for more runs without needing to compile the source.

prompt$ ./simple-data
simple-data.cob example                                         
compute 6 times 7                                               
answer is:                                                      
42

Same answer. Which is good. Computers would be much less useful if results were not consistent. COBOL programmers need to write programs that have consistent results, as this keeps everyone’s bank balance from indiscriminately changing.

Of note is that the identifier program-message is a fixed length 64 character variable, defined as PIC X(64). COBOL will fill in any remaining character positions with spaces during a MOVE to that field. And the DISPLAY verb actually prints all 64 characters each time.

For a demonstration, the program is run again with the output passed through the tr utility; all spaces translated to dots so you can see them.

prompt$ ./simple-data | tr ' ' '.'
simple-data.cob.example.........................................
compute.6.times.7...............................................
answer.is:......................................................
42

Don’t worry, we’ll learn an easy way to avoid displaying the trailing spaces soon enough. For the impatient, there is an intrinsic function, called TRIM.

Of other note is that the identifier answer is a two digit numeric field, defined with PIC 99. That field would be incapable of properly storing or displaying any number less than zero or greater than ninety-nine. And again, don’t worry, we’ll see ways of allowing for much larger (and negative) values, shortly. For the impatient, you’ll have to wait, as the PICTURE clause includes an overwhelming number of details that require a lot of explanation.

1.28.9   Source formats

A short side trip into source formats. GnuCOBOL supports two forms of program text. SOURCE FORMAT IS FIXED and SOURCE FORMAT IS FREE. For historical reasons, the default compile mode is FORMAT FIXED.

Source lines are divided up in parts. Columns 1-6 hold a sequence number, any characters allowed, ignored by the compiler, and historically used to help humans keep track of the order of source lines. (When a deck of punch cards was dropped on the floor, chaos ensued getting the cards back in the proper order). Column 7 is an indicator column, and an asterisk in column 7 informs the compiler to ignore the entire line as a comment line, only meant for human readers. Column 8 through 72 holds the actual compiler instructions.

In the listing below, the line of numbers is just a ruler line to help count the columns. It has a an asterisk in column 7, and COBOL will treat the whole thing as a comment line..

123456*89012345678901234567890123456789012345678901234567890123456789012

000100*  This is a comment line
000200 IDENTIFICATION DIVISION.
000300 ...

To avoid that complication from now on we will use a new cobc compiler switch, -free, which puts the compiler into a more modern free format mode. Because there is no longer a special indicator column, comments will use a more modern syntax of two characters, *>. The two character form of comments can be placed anywhere on the line, and all text afterwards will be ignored by the compiler until the next line starts.

I’m in the habit of placing the two characters such that the asterisk is still in column 7, but that is an old habit, and -free compilation will free you from that historical burden (which isn’t a burden, but it still looks old, and who wants to look old).

1.28.10   Flow of control

That heady sounding expression is just another way of stating that programs run in a predictable order. Also termed control flow. Unless told otherwise, GnuCOBOL programs execute from the top of the source code down, each line executed in sequence. The first line executes, then the second, then the third, as so on. This sequential processing is built into COBOL, and you don’t have to tell the compiler anything special to have that happen. It is a natural state of most programming. Execute statements, in the order given in a source listing, until told otherwise.

Along with sequential processing, computers also do conditional and iterative processing. IF statements and loops.

Let’s start with a conditional expression.

1.28.11   Conditionals

The IF statement. If something is true, do this, otherwise skip it. And a more complete, if something is true, do this, otherwise do that.

More typing, save this file as just-if.cob:

      *>
      *> just-if.cob, GnuCOBOL FAQ tutorial
      *>
       identification division.
       program-id. just-if.

       data division.
       working-storage section.
       01 result               pic 999.

       procedure division.

       multiply 6 by 7 giving result

       if result is less than 100 then
           display "The ultimate answer seems reasonable: " result
       end-if

       if result is greater than or equal to 100 then
           display "There is something wrong with the universe: " result
       end-if

       goback.
       end program just-if.

tutorial/just-if.cob

That program introduces the IF statement. The first IF is the one we expect to ring true, 6 times 7 being less than 100. There is also the END-IF statements. These tell the compiler where to end a conditional branch fragment.

Skipping ahead a little. The full stop period is also a way of terminating a sequence of code in a conditional block, but that use can lead to subtle, hard to spot errors. A full stop will terminate ALL nested IF conditionals, and that can sometimes be the wrong thing to do. The recommendation is to use the scope terminator reserved words when you need to delimit blocks of code. These are much easier to spot than small dots in the source code.

The second test in just-if.cob will not display any message unless there is something seriously wrong with the computer, or the universe in general. We know that 6 times 7 is less than 100. You will rarely see such blatantly predictable false code except in test suites that are verifying a compiler or other unit testing frameworks.

prompt$ cobc -free -x -j just-if.cob
The ultimate answer seems reasonable: 042

just-if.cob also introduces another feature of COBOL. Full english statements for math calculations and conditionals. It is a design feature of COBOL. Some programmers find it far too verbose to have to type MULTIPLY; but non programmers have a much higher chance of knowing what is going on when reading the words instead of some computer glyph symbol (like the asterisk, which means multiply in many programming languages, and in COBOL COMPUTE statements).

COBOL was designed to help business people solve business problems and it is deemed polite, and beneficial, to at least attempt to allow business managers, that may not be programmers, to reason through some of the calculations performed when programs are running to manage their business.

The same level of verbosity was used for the IF statement. Full words for IS GREATER THAN, OR EQUAL TO and LESS THAN. GnuCOBOL will allow for more symbolic forms as well.

      *>
      *> just-if-symbols.cob, GnuCOBOL FAQ tutorial
      *>
       identification division.
       program-id. just-if-symbols.

       data division.
       working-storage section.
       01 result               pic 999.

       procedure division.

       compute result = 6 * 7

       if result < 100 then
           display "The ultimate answer seems reasonable: " result
       end-if

       if result > 100 then
           display "There is something wrong with the universe: " result
       end-if

       goback.
       end program just-if-symbols.

tutorial/just-if-symbols.cob

Same output as before, but using source code slightly less suitable for non programmers. COBOL is flexible enough to allow both, and the context should determine who a program is written for. Some managers, developers and customers will prefer the full long form, others may prefer the shorter symbolic form.

prompt$ cobc -free -x -j just-if-symbols.cob
The ultimate answer seems reasonable: 042

And a note on the promise of FORMAT FREE versus FORMAT FIXED. The author of this tutorial actually prefers FIXED format COBOL, but from now on, the source listings are crafted to allow both modes of compile. That code could also be formatted as:

*>
*> just-if-free.cob, GnuCOBOL FAQ tutorial FORMAT FREE example
*>
identification division.
program-id. just-if-free.

data division.
working-storage section.
01 result               pic 999.

procedure division.

multiply 6 by 7 giving result

if result is less than 100 then
    display "The ultimate answer seems reasonable: " result
end-if

if result is greater than 100 then
    display "There is something wrong with the universe: " result
end-if

goback.
end program just-if-free.

tutorial/just-if-free.cob

But now, cobc has to be told to compile in a free format friendly manner.

prompt$ cobc -free -x -j just-if-free.cob
The ultimate answer seems reasonable: 042

All further samples will be written to allow either -free or -fixed compile modes. -fixed is the default, -free is more modern.

cobc will complain loudly if that last example is compiled assuming fixed format.

prompt$ cobc -x -j just-if-free.cob
just-if-free.cob: 2: error: invalid indicator 'h' at column 7
just-if-free.cob: 3: error: invalid indicator 'i' at column 7
just-if-free.cob: 5: error: invalid indicator 'e' at column 7
just-if-free.cob: 6: error: invalid indicator 'i' at column 7
just-if-free.cob: 8: error: invalid indicator 't' at column 7
just-if-free.cob: 9: error: invalid indicator 'o' at column 7
just-if-free.cob: 13: error: invalid indicator 't' at column 7
just-if-free.cob: 15: error: invalid indicator 'f' at column 7
just-if-free.cob: 16: error: invalid indicator 'm' at column 7
just-if-free.cob: 18: error: invalid indicator 'i' at column 7
just-if-free.cob: 19: error: invalid indicator 'g' at column 7
just-if-free.cob: 20: error: invalid indicator 'u' at column 7
just-if-free.cob: 22: error: invalid indicator 'u' at column 7
just-if-free.cob: 24: error: invalid indicator 'l' at column 7
just-if-free.cob: 26: error: invalid indicator 'u' at column 7
just-if-free.cob: 27: error: invalid indicator 's' at column 7
just-if-free.cob: 30: error: invalid indicator 'u' at column 7
just-if-free.cob: 31: error: invalid indicator 's' at column 7
just-if-free.cob: 34: error: invalid indicator '.' at column 7
just-if-free.cob: 35: error: invalid indicator 'o' at column 7
just-if-free.cob: 36: error: PROGRAM-ID header missing

As a protective measure, GnuCOBOL includes an in source directive that can be used to alleviate remembering to pass -free to cobc every time. Due to the default way that cobc starts, the initial directive must occur at the very top of the file, and it must start in column 8 or greater.

>>SOURCE FORMAT IS FREE

As a pleasantry, all sources will now include that line, or a similar directive to explicitly state that the assumed source mode is FIXED.

*>GCOB >>SOURCE FORMAT IS FREE
      *>-<*
      *> Author: Brian Tiffin
      *> Dedicated to the public domain
      *>
      *> Date started: January 2017
      *> Modified: 2017-01-29/17:28-0500
      *>
      *> Tectonics:
      *>   cobc -x just-if.cob
      *>   ./just-if
      *>+<*
      *>
      *> just-if.cob, GnuCOBOL FAQ tutorial
      *>
       identification division.
       program-id. just-if.

       data division.
       working-storage section.
       01 result               pic 999.

       procedure division.

       multiply 6 by 7 giving result

       if result is less than 100 then
           display "The ultimate answer seems reasonable: " result
       end-if

       if result is greater than 100 then
           display "There is something wrong with the universe: " result
       end-if

       goback.
       end program just-if.

tutorial/just-if-format.cob

That listing, includes all the preamble text that is part of the downloadable copies of these tutorial entries, to show the directive.

Also note the *>GCOB marker is ignored by the compiler. Fixed format source (which all programs start out in by default) skips over the first 6 columns of every line in a program. It is one of the reasons I like FIXED form, it allows for small notes in the margins. In this case a trick is used, and the marker is actually a valid comment, so that source will work in either mode. It also satisfies a requirement of being friendly to the markup processor used to produce this document, which uses indentation based highlighting and paragraph detection logic, but that has nothing to do with COBOL really.

Have I ever mentioned that COBOL includes an overwhelming number of details, best left out of an introductory tutorial?

1.28.12   If else

Now finally to the second form of conditional, IF true THEN do-this ELSE do-that.

More typing. This time edit a file called ifelse.cob.

      *>
      *> ifelse.cob, GnuCOBOL FAQ tutorial
      *>
       identification division.
       program-id. ifelse.

       data division.
       working-storage section.
       01 result               pic 99.

       procedure division.

       multiply 6 by 7 giving result

       if result equals 42 then
           display "The ultimate answer is still " result
       else
           display "There is something wrong with the universe: " result
       end-if

       goback.
       end program ifelse.

tutorial/ifelse.cob

This time around one of the display statements will execute depending on the conditional test. Same compile command model as before cobc -xj, as captured below.

prompt$ cobc -xj ifelse.cob
The ultimate answer is still 42

If all is right with the universe then that program just output:

The ultimate answer is still 42

That program sample is compiled during generation of this document (every time). There is no absolute guarantee that I didn’t break something and that the universe is still ok. In all likelihood, the expectation matches the actual. I work on the compiler, and sometimes mistakes are made on the local install. Those mistakes are always short lived, but may influence the generation of some releases of this tutorial.

Note

The THEN reserved word is optional, and some COBOL programmers find it wasteful to include in source code. I find it reassuring and it reads well.

And by the way, the whole 42 thing is from The Hitchhiker’s Guide to the Galaxy, by Douglas Adams. A very worthy “trilogy” of six science fiction books. Along with 42 the books also emphasize a motto of “Don’t panic”.

1.28.13   Branching

Along with conditional do-this or do-that branching, flow of control change in COBOL can also be caused by jumping around. And there are two forms of jumping around. A controlled, go there and come back here, and the less controlled, go there, with no real come back here part.

The controlled form is via PERFORM. The less controlled form is via GO TO. There is also CALL, but we’ll get to that very powerful verb a little later.

1.28.14   Perform branching

COBOL includes various forms of a PERFORM statement. A looping form, discussed soon, and a simple branch to and come back here form, discussed here.

Time to fire up the editor again, and create a file called performing.cob.

      *>
      *> performing.cob, GnuCOBOL FAQ tutorial
      *>
       identification division.
       program-id. performing.

       data division.
       working-storage section.
       01 counter              pic 9   value 1.

       procedure division.

      *> normal flow starts here
       display counter
 
      *> then branches to a procedure, then returns back
       perform increment-counter
    
      *> and carries on with the next line
       display counter

      *> then we return to the caller, in this case the operating system
       goback.

      *> a named paragraph 
       increment-counter.
           add 1 to counter
       .

       end program performing.

tutorial/performing.cob

That program will start at the top, then branch to a subroutine (formally a procedure) and then return to the line following the PERFORM to continue sequential line by line execution.

To run it, type cobc -xj performing.cob as in this captured example:

prompt$ cobc -xj performing.cob
1
2

That sample introduces labels, or named paragraphs, to the COBOL repertoire. A user defined identifier used as a named label (requires a full stop as part of the name definition, and that full stop has implications on the normal sequential top down processing rules inherent in COBOL). More on that later.

And now for a much maligned form of flow control. Uncontrolled jumping around.

1.28.15   Going, going, ...

GO TO has been supported in COBOL since times before structured programming became the status quo. ALGOL had structured programming back in those early days, but other contemporaries of the era, like early FORTRAN compilers, did not. There are very few programming languages in current use that do not support structured programming. Assembly may be the only one in the main stream, and even some assemblers allow structured techniques on the way to machine code. Early BASIC programming was also squarely (and famously) in the not structured camp.

Some languages include go to branching, some do not. Many programmers eschew the go to, but there are times when it is a very efficient way of handling control flow. Errors or early exit conditions from a complex function is one common use case. The C language allows goto, Java does not support this type of branching (by name). Common structured elements such as break, continue and/or next in other programming languages, are all actually a form of go branching`, without being named go to. Most of these keywords imply “go to the bottom” or “go to the top” of this code block.

GOTO by Randall Munroe

XKCD, http://xkcd.com/292/ by Randall Munroe, CC BY-NC 2.5

The next sample is not that brilliant. It simply jumps around for the sake of demonstration.

More typing, this time into a file called going.cob.

      *>
      *> going.cob, GnuCOBOL FAQ tutorial
      *>
       identification division.
       program-id. going.

       data division.
       working-storage section.
       01 counter              pic 9   value 1.

       procedure division.

      *> normal flow starts here
       display counter
 
      *> then jumps
       go to the-bottom
    
      *> this is dead code, never executed
       display "Why am I even here?"

      *> the following full stop is required so that GnuCOBOL
      *> knows that this part of the program is terminated and to allow
      *> the next named paragraph to be recognized.
       .

      *> a named paragraph 
       the-bottom.
           display "Jumped to the-bottom"
      
      *> then we return to the caller, in this case the operating system
       goback.

       end program going.

tutorial/going.cob

The sample simply starts at the top, jumps to the bottom and exits. Don’t write programs like this. Except during development phases where you are experimenting and need to jump over a bunch of code that is unrelated to the task at hand, knowing full well that the GO TO will be removed as soon as possible. To compile and run the job, type cobc -xj going.cob as demonstrated below:

prompt$ cobc -xj going.cob
1
Jumped to the-bottom

GnuCOBOL includes a cobc feature to help find fragments of dead code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
*>GCOB*>-<*
      *> Author: Brian Tiffin
      *> Dedicated to the public domain
      *>
      *> Date started: January 2017
      *> Modified: 2017-01-29/17:26-0500
      *>
      *> Tectonics:
      *>   cobc -x going.cob
      *>   ./going
      *>+<*
      *>
      *> going.cob, GnuCOBOL FAQ tutorial
      *>
       identification division.
       program-id. going.

       data division.
       working-storage section.
       01 counter              pic 9   value 1.

       procedure division.

      *> normal flow starts here
       display counter
 
      *> then jumps
       go to the-bottom
    
      *> this is dead code, never executed
       display "Why am I even here?"

      *> the following full stop is required so that GnuCOBOL
      *> knows that this part of the program is terminated and to allow
      *> the next named paragraph to be recognized.
       .

      *> a named paragraph 
       the-bottom.
           display "Jumped to the-bottom"
      
      *> then we return to the caller, in this case the operating system
       goback.

       end program going.
prompt$ cobc -x going.cob -Wunreachable
going.cob: 31: warning: unreachable statement 'DISPLAY'

Not saying much more about that example, other than it should be short lived. It might help during isolation testing. Don’t let your peers see that code unless they are helping you debug a problem.

More practical use of GO TO is the common idiom of jumping to the bottom of a long sequence of code. If conditions are met so that further processing is no longer required, just GO TO bottom-of-routine-label.

As stated, some purists eschew this idiom, but in practice, using GO can often avoid artificial conditional branching blocks, which can become quite messy when nested in complex code sequences. As a GnuCOBOL programmer, you are free to choose the style you prefer. In some cases you are free to choose the style dictated by the project manager (or risk expulsion by velociraptor).

Note

Many languages use a keyword of goto, the COBOL verb is actually GO, with an optional TO reserved word. In GnuCOBOL GOTO is a syntax error, use GO label or GO TO label.

1.28.16   Selective evaluation

A third form of branching is the selective evaluation mechanism. A complete set of options is listed and tested, and the program will execute the first set that tests true. In COBOL this uses the EVALUATE verb in tandem with an unlimited number of WHEN clauses.

*>GCOB*>-<*
      *> Author: Brian Tiffin
      *> Dedicated to the public domain
      *>
      *> Date started: January 2017
      *> Modified: 2017-01-30/01:15-0500
      *>
      *> Tectonics:
      *>   cobc -x evaluating.cob
      *>   ./evaluating
      *>+<*
      *>
      *> evaluating.cob, GnuCOBOL FAQ tutorial
      *>
       identification division.
       program-id. evaluating.

       data division.
       working-storage section.
       01 first-field           pic 9.
       01 second-field          pic X.

       procedure division.

       move 1 to first-field
       move "C" to second-field

      *> inside a when conditional, the subject need not be mentioned
       evaluate first-field also second-field
           when = 1         also = "A"
               display "1A"
           when = 1         also = "B"
               display "1B"
           when = 1         also = "C"
               display "1C"
               display "This is the when block that executes"
           when = 1         also any
               display "This is also true, but the first one wins"
           when other
               perform no-matches
       end-evaluate

       goback.

       no-matches.
           display "No matches found: " first-field ", " second-field
       .
       end program evaluating.

tutorial/evaluating.cob

EVALUATE is a very powerful selective evaluation statement, even when compared to most modern programming languages. The multiple condition testing allows for very concise multi-branch logic tables. Perfect for the business domain with complex conditions within conditions logic layering.

So, go ahead and type in evaluating.cob. Then run it with:

cobc -xj evaluating.cob

Example run:

prompt$ cobc -xj evaluating.cob
1C
This is the when block that executes

A nice feature of WHEN is that the subject field does not need to be mentioned. Each test assumes the field name before the conditional expression.

Using a fragment from the example above:

WHEN = 1 also = "A"

That is equivalent to

WHEN first-test = 1 ALSO second-test = "A"

Not only that, but range testing is allowed.

WHEN = 1 ALSO = "A" THRU "Z"

The evaluate verb can compress a lot of conditional testing into a very small table like structure. Multiple statements are allowed within each WHEN block.

1.28.17   Other forms of branching

COBOL includes a few other ways of branching; computed GO TO, ALTER, and DECLARATIVES. These will be covered later.

1.28.18   Loops

Let’s take a look at another form of control flow. The loop. COBOL has a more restrictive take on looping than some other programming languages. All loops are either self managed by labels and GO TO statements, or through the PERFORM verb.

Strict structured programming practitioners treat GO TO as anathema, to be avoided, so let’s start with one of those.

More typing, this time into a file called goloop.cob.

      *>
      *> goloop.cob, GnuCOBOL FAQ tutorial
      *>
       identification division.
       program-id. goloop.

       data division.
       working-storage section.
       01 counter              pic 9   value 1.

       procedure division.

       loop-here.

           display counter
           add 1 to counter
           if counter < 4 then GO TO loop-here end-if
       .

       goback.
       end program goloop.

tutorial/goloop.cob

And a sample run:

prompt$ cobc -xj goloop.cob
1
2
3

Seeing as that listing probably makes some people angry about teaching the GO verb, no more will be said about it. Ok, one thing. Use GO TO with care and understanding, don’t just be jumping around a program because it seems easier at the time.

1.28.19   Loop forms

A side trip. Most programming languages support:

while condition do loop-block
do loop-block until condition

COBOL supports:

perform until condition loop-block

The default for that is WITH TEST BEFORE which ends up being equivalent to a while NOT condition do loop-block sort of backwards form.

The qualifier clause WITH TEST AFTER creates an equivalent of the do loop-block until condition form.

All the usual forms of loop are possible, but the syntax is not quite as straight forward as some programmers may be accustomed to.

A common idiom in COBOL is a “prime the pump” loop form. Do an initial action that sets the condition and other initial data values. Start the loop body, and then end the loop body with the action that sets the condition. This seems redundant, but it is actually a fairly robust and reliable way of programming loops. You have to duplicate an action, but it often means there are less fencing issues and off by one errors inside the loop body proper. This becomes equivalent to a slightly safer:

pre-condition
while condition do loop-block

Now forget all that for the moment, and let’s focus on the forms of loops provided by COBOL syntax.

1.28.20   Perform loops

COBOL includes two types of PERFORM. Inline and out-of-line. Inline is the modern, out-of-line is an older procedure branch and return form and is still very prevalent in COBOL programs.

First an out-of-line procedure PERFORM. Named paragraphs and sections are called procedures in COBOL. Sadly they do not accept arguments, nor can they return results. Most COBOL programming comes down to side effect by changing globally accessible variables. Not completely terrible, all things considered, but it is a cause of more verbosity in COBOL, and a reason to show care and attention when developing larger programs.

Functional programming purists probably cringe at the thought of programming via side effect, but it has suited business programming for over 50 years now and banks still seem to keep all our account balances properly tallied.

to be continued

1.28.21   Syntax errors

Syntax errors are common when developing programs. A misspelt word, a missed punctuation character, or some critical ordering mix up. The cobc compiler will tell you the line numbers where trouble brews, along with an explanatory error message.

Unfortunately, some syntax errors lead to an out of synch compile pass, and a whole raft of unrelated error messages may ensue. Start at the first one, fix it, and then recompile. Keep repeating the Edit -> Compile -> Edit -> Compile cycle until all syntax errors are corrected.

Typos happen. The compiler will tell you about them. It is very rare to have programs work on the very first compile. Get used to that as a normal part of software development. And as a reminder to always test things, even after what seem like insignificant changes. Typos happen.

1.28.22   Logic errors

Aside from syntax errors, logic errors are much more insidious. The compiler will dutifully compile programs that won’t do the correct thing. This is where the human mind wins out over computers. Adding numbers together at speed is a computer strength. Knowing what numbers to add together is the human advantage. Informing a computer of what numbers to add together when (and how) is the job of the computer programmer. Along with support from others to ensure that the calculations are done properly and are of practical use is the domain of software development.

GnuCOBOL has quite a few tools to assist with testing and debugging programs. There are statement tracers to allow capturing the steps taken and in what order. There are low level debuggers, such as gdb that can be used for very detailed analysis of what is happening during a program run. There are profiling tools to help find where performance bottle necks are occurring. And a host of other automated and manual techniques that come into play during the verification and validation of COBOL programs.

1.29   Do you know any good jokes?

Maybe.

  • A computer without COBOL and Fortran is like a piece of chocolate cake without ketchup or mustard.

    John Krueger

  • A determined coder can write COBOL programs in any language.

    Author: unknown

  • Rumour has it that the object oriented specification for COBOL was code named

    ADD 1 TO COBOL GIVING COBOL.

    Author: unknown

    A less verbose, more concise version; very unCOBOL that

    ADD 1 TO COBOL.

    Thanks to aoirthoir

    And, just because;

    ADD 1 TO COBOL GIVING GnuCOBOL

  • A common disrespect of COBOL joke is that the acronym stands for:

    Completely Obsolete Business Oriented Language.

    Author unkown

    We know better. The reality is:

    Can’t Obsolesce Because Of Legacy. And why would you want to?

    Brian Tiffin

  • COBOL

    Certainly Old But Often Limber.

    Brian Tiffin

  • Ruby on Rails? Don’t forget COBOL ON COGS.

    http://www.coboloncogs.org/INDEX.HTM

  • Eat COBOL, 200 billion lines can’t be wrong.

    Brian Tiffin

  • What did COBOL yell to the escaping thief?

    STOP RUN RETURNING NOW.

    Brian Tiffin

  • A COBOL programmer’s husband asks, “Honey can you go to the store and get some milk. And if they have eggs, get a dozen.” After twenty minutes she returns and flops 12 bags of milk on the table. He looks at her curiously, “Honey, why did you do that?” She responds flatly, “They had eggs.”

    Author unknown

  • What did COBOL reply to the executive? Yes, I can

    PERFORM JUMPS THRU HOOPS.

    Brian Tiffin

  • What did GnuCOBOL reply to the executive? Sir, I can

    PERFORM JUMPS THRU FLAMING-HOOPS UNTIL HELL-FREEZES-OVER.

    And being COBOL, I have to show you how little code it takes:

identification division.
program-id. freeze.

data division.
working-storage section.
01 hell                   pic 9.
   88 hell-freezes-over value 1.

procedure division.
perform jumps thru flaming-hoops until hell-freezes-over.
stop run.

jumps.
flaming-hoops.
divide 1 by 0 giving hell.
  • Wrote COBOL all morning, all afternoon and into the night. Another carpe, diem’ed.

    Brian Tiffin, ripped from a meme, then farberized

  • The lady down the street didn’t believe I could build a car out of spaghetti.

    You should have seen the look on her face when I drove pasta.

    Author unknown

  • This is your captain speaking.

    THIS IS YOUR CAPTAIN SHOUTING.

    Author unknown

  • How many COBOL programmers does it take to change a light bulb?

    One. COBOL programmers understand how the world works, they can change a light bulb. Which then lets them see their keyboard so they can fill out screen PF103D, submit job LB103R and request approval for a backup T5W-60.

    Brian Tiffin

1.29.1   Really?

Ok, sorry for the lame.

Here is a link to some actual humour; Bob the Dinosaur, thanks to Scott Adams.

http://dilbert.com/strips/comic/1997-11-04/

And another one; Grace Hopper, by Zach Weinersmith at Saturday Morning Breakfast Cereal.

http://www.smbc-comics.com/?id=2516 (with a small snip from the actual comic, Copyright 2012 Zach Weiner)

_images/smbc-hopper.png

Zach also coined the phrase, “off-by-frog”.

http://www.smbc-comics.com/?id=2831

That comic spawned the writing of frogSort, officially known as the Weinersmith Fly By Frog Sort, or weiner sort.

Sorry, back to lame; sweet, sweet, lame.

*> ********************************************************
*>  frogSort, called for help with 10-94, request for count
*>  The Weinersmith Fly By Frog Sort, weiner sort for short
*> ********************************************************
 identification division.
 program-id. frogsort.
 data division.
 working-storage section.
 01 opinion          usage binary-long.
 01 shared-value     pic 99.
    88 fair          value 1.
 01 caveman-count    pic x(12) value "[-]+++++++++".
 01 spacer           pic x(10) value spaces.

 linkage section.
 01 jars.
    05 flies        pic 9 occurs 21 times.

*> ********************************************************
 procedure division using jars.
 start-here.
 move function length(jars) to shared-value
 display "Grog sort jars.  frogSort"
 display "http://www.smbc-comics.com/?id=2831"
 .

 forkanother.
     call "fork" returning opinion end-call
     if opinion is zero then
         subtract 1 from shared-value
         if not fair then go forkanother.
 .

 call "sleep" using by value flies(shared-value) end-call
 display
     "Jar: " function char(shared-value + 65) " reporting "
     caveman-count(1 : flies(shared-value) + 3) " flies,"
     spacer(1 : 10 - flies(shared-value))
     "that would be " flies(shared-value) " to you, futureman."
 call "wait" using by value 0

 stop run returning 107.
 end program frogsort.

Which is an easter egg in the cbrain esoteric programming language, when requesting help for Citizen Band code 10-94, Request for long count. Returns CB code 10-7, Leaving air, radio off.

prompt$ ./cbrainrun
10-12 Welcome to cbrain v0.42
cb: 1094
cb: help
Grog sort jars.  frogSort
http://www.smbc-comics.com/?id=2831
Jar: U reporting [-] flies,          that would be 0 to you, futureman.
Jar: K reporting [-] flies,          that would be 0 to you, futureman.
Jar: A reporting [-] flies,          that would be 0 to you, futureman.
Jar: L reporting [-]+ flies,         that would be 1 to you, futureman.
Jar: B reporting [-]+ flies,         that would be 1 to you, futureman.
Jar: M reporting [-]++ flies,        that would be 2 to you, futureman.
Jar: C reporting [-]++ flies,        that would be 2 to you, futureman.
Jar: N reporting [-]+++ flies,       that would be 3 to you, futureman.
Jar: D reporting [-]+++ flies,       that would be 3 to you, futureman.
Jar: O reporting [-]++++ flies,      that would be 4 to you, futureman.
Jar: E reporting [-]++++ flies,      that would be 4 to you, futureman.
Jar: P reporting [-]+++++ flies,     that would be 5 to you, futureman.
Jar: F reporting [-]+++++ flies,     that would be 5 to you, futureman.
Jar: Q reporting [-]++++++ flies,    that would be 6 to you, futureman.
Jar: G reporting [-]++++++ flies,    that would be 6 to you, futureman.
Jar: R reporting [-]+++++++ flies,   that would be 7 to you, futureman.
Jar: H reporting [-]+++++++ flies,   that would be 7 to you, futureman.
Jar: S reporting [-]++++++++ flies,  that would be 8 to you, futureman.
Jar: I reporting [-]++++++++ flies,  that would be 8 to you, futureman.
Jar: T reporting [-]+++++++++ flies, that would be 9 to you, futureman.
Jar: J reporting [-]+++++++++ flies, that would be 9 to you, futureman.

1.29.2   A 5-7-5 haiku?

How about a 5-7-5 haiku?

 program-id. one.
 procedure division. add
 1 to return-code.

*btiffin*

Compiles to a program that returns a failure code when run. Fails as poetry, fails as code. Your welcome.

I wasn’t allowed to post that as an actual Haiku on wikipedia. Call it a 5-7-5. Because, it isn’t, really, Haiku.

So...ummm, it could be program-id. sun. or...

springing into life
soaking sun, drinking summer
falling to winter

Take that. I respect the wikipedia discussion decision, but come on, program one compiles and executes. Even if it was based on Canadian elementary and high-school, missing the point, 5-7-5 fake haiku.

_images/bluesmile.png

1.29.3   One in cbrain

0[5-7-5 in cbrain]

 72 . 65
. 73 . 75 .
 85 . 42

Displaying HAIKU and returning 42.

2   History

2.1   What is the history of COBOL?

Starting in 1959, a committee was formed under the sponsorship of the United States Department of Defense to recommend a short range option regarding business computing. The Conference on Data System Languages (CODASYL) led by Joe Wegstein of National Bureau of Standards (now National Institute of Standards and Technology) developed a new language, and created the first standardized business computer programming language.

The COmmon Business Oriented Language acronym was announced on September 18th, 1959.

Late in 1960, essentially the same COBOL program ran on two different hardware platforms, and stakeholders espied the potential for fulfilling the objective of industry wide, compatible business systems.

Rear Admiral Grace Hopper is affectionately referred to as the (grand)mother of the COBOL language, as she and her previous work with FLOW-MATIC, greatly influenced the specifications of the first COBOL. She is said to have argued strongly for words over symbols. So, COBOL has ADD, SUBTRACT, MULTIPLY, and DIVIDE and not just +, -, *, and /.

_images/gracehopper-1961.jpg

Grace Hopper discussing COBOL in 1961.

Courtesy of Jeffrey Chuan Chu, and the Computer History Museum. http://www.computerhistory.org/collections/catalog/102722559

Grace is often referred to as Admiral Grace Hopper. She was not actually an admiral. She was promoted to captain by the United States Navy in 1973, then, by special Presidential appointment, to commodore in 1983. The rank title of commodore was officially changed by the Navy in 1985, to rear admiral (lower half).

2.1.1   Published Standards

Standards have been published for:

  • COBOL-68
  • COBOL-74
  • COBOL-85
  • COBOL-89 Intrinsic Functions
  • COBOL-2002
  • COBOL-2014

and these roughly correspond to the year they were produced. Note the y2k flavour of four digit naming occurred after the millennium change. Again, please note that these are not offical titles. Official titles look more like the newest one (2014), shown here:

ISO/IEC 1989:2014 Information technology – Programming languages, their environments and system software interfaces – Programming language COBOL, which was published in May 2014.

See the Wikipedia entry for COBOL which has a lot more details. Including names other than just Grace Hopper, who also deserve to be credited with the initial design and implementation of what was eventually named COBOL-60.

2.1.2   The Gartner estimate

Estimates vary, but it is reasonable to believe that of the some 300,000,000,000 (three hundred thousand million, 300 billion) lines of computer source code in production as of 1995, 200,000,000,000 (200 billion) lines were COBOL. A full 2/3rds of the world’s source code at the time.

Please note: the above line count estimate is approaching urban legend status and its reutterance is frowned upon now. I looked, and only witnessed a cycle of referenced material, but found no material. Besides, it’s an old number.

Even then, there was, is, and will be, a lot of source form COBOL. A lot.

Compiled COBOL literally (literately?) dominates in many core critical Business, and perhaps even some Engineering computing areas. When records and fields are being processed, like say financial transactions or inventories, COBOL shines in legible correctness. Words and not always just code. Good for business. Started that way in 1959, still that way; and more, now and into the unforseeable future.

2.2   What are the Official COBOL Standards?

Many thanks to William Klein, [wmklein] for details on what wordings are to be used when referencing COBOL Standards:

There are several references to "COBOL 85" and these are often
distinguished from "Intrinsic Functions".

The official (but really obscure) term that should be used is "Amended
Third Standard COBOL". The "clearer" (and IMHO better) term that should
be used is something like

 - "'85 Standard COBOL with its amendments"

By 1991 (actually 1993 for ISO rather than ANSI) there was no such thing
as "just '85 Standard COBOL". The only recognized Standard was the
"base" document (X3.23-1985) ALONG with its two amendments
 - Intrinsic Functions Module Amendment
 - Corrections Amendment

An interesting related fact is that the "Intrinsic Functions Module" was
OPTIONAL in the ANSI and ISO COBOL Standards but was REQUIRED (at the
HIGH level) for FIPS COBOL. As the "certification tests" were aimed at
getting US government contracts, most vendors (who were still doing
certification) actually treated Intrinsic Functions required not
optional for "High-level" certification. (They were NOT included in the
FIPS intermediate certification process).

Bottom-Line:
 Although some intrinsic functions were added in the '02 Standard (and
more are included in the draft revision), it is not proper (in my
opinion) to distinguish between supporting the '85 Standard and
supporting intrinsic functions.

P.S. The corrections amendment did make some technical changes but all
of these were included in the '02 Standard. Therefore, hopefully, what
it did won't impact OpenCOBOL much.

2.2.1   COBOL 2014

ISO/IEC 1989:2014 Information technology – Programming languages, their environments and system software interfaces – Programming language COBOL, was published in May 2014.

http://www.iso.org/iso/home/store/catalogue_tc/catalogue_detail.htm?csnumber=51416

There is a pre-vote copy stashed away at open-std.org

http://www.open-std.org/jtc1/sc22/open/ISO-IECJTC1-SC22_N4561_ISO_IEC_FCD_1989__Information_technol.pdf

Note

While GnuCOBOL can be held to a high standard of quality and robustness, the authors do not claim it to be a “Standard Conforming” implementation of COBOL.

2.3   What is the development history of GnuCOBOL?

OpenCOBOL was initially developed by Keisuke Nishida [Keisuke] from experience working on TinyCOBOL originally developed by Rildo Pragana.

The first public release was version 0.9.0 on January 25th, 2002.

Development continued apace, with version 0.30 released by Keisuke on August 8th, 2004.

Roger While [Roger] then took up the role as lead developer on October 30th, 2004.

Simon Sobisch accepted the role of project lead on August 6th, 2014.

Sergey Kashyrin [Sergey] posted the C++ emitter, GnuCOBOL 2.0 CPP on September 27th, 2013. The same day Richard Stallman dubbed OpenCOBOL an official GNU project, as GNU Cobol. Sergey followed along with the rename. September 21st, 2014, the spelling change to GnuCOBOL.

Ron Norman [Ron] had code posted for Report Writer, which became GnuCOBOL with Report Writer on November 23rd, 2013.

Version 0.9
Keisuke publicly announced OpenCOBOL on January 25th, 2002.
Version 0.30
was released on August 8th, 2004.
Version 0.31
was released February 1st, 2005.
Version 0.32
was released May 12th, 2005.
Version 0.33
started on May 13th, 2005.
Version 1.0
was released on December 27th, 2007.
Version 1.1
was released on SourceForge on May 4th, 2012.
Version 1.1CE
went into active development on May 4th, 2012.
Version 2.0
was released in September 2013.
Version 2.0 CPP, C++
was released in September 2013.
Version 2.0rc-1
was released on SourceForge on August 13th, 2016.
Version 2.0rc-2
was released on SourceForge on November 6th, 2016.
Report Writer Version
was posted to SourceForge for trial in November 2013.
GNU
OpenCOBOL was accepted as an official GNU project on September 27th, 2013 and was rebranded as GNU Cobol.
GNU Cobol version 1.1
was posted with a digital signature to ftp.gnu.org/gnu/gnucobol on January 18th, 2014. Due to a mismatch caused during build testing, the first cut source kit was replaced, January 20th, 2014.
GnuCOBOL
GnuCOBOL became the preferred spelling on September 21st, 2014.
FSF
Copyright ownership for the entire OpenCOBOL (now GnuCOBOL) source tree by the Free Software Foundation become legally binding on June 17th, 2015. This copyright reassignment covers all releases of the source code, dating back to Keisuke’s original 0.9 public announcement in 2002.

2.4   What is the current version of GnuCOBOL?

ftp://ftp.gnu.org/gnu/gnucobol/gnu-cobol-1.1.tar.gz is the official GNU release.

GnuCOBOL has finally entered a 2.0 beta release phase. Latest official download source kit on SourceForge is GnuCOBOL-2.0rc2. That source kit and a Windows centric source package can be found at

https://sourceforge.net/projects/open-cobol/files/gnu-cobol/2.0/

Older releases

Simon Sobisch has put together a MinGW binary build of GnuCOBOL 1.1 for use with Windows(tm), hosted at http://sourceforge.net/projects/open-cobol/files/gnu-cobol/1.1/ file name is GnuCOBOL_1.1_MinGW_BDB_PDcurses_MPIR.7z

Other versions include:

  • 1.1 Stable by Keisuke Nishada and Roger While
  • 2.0 Pre-release with FUNCTION-ID support by Roger While.
  • 2.0 C++ emitter by Sergey Kashryin

These are all on SourceForge at http://sourceforge.net/p/open-cobol/code/

http://sourceforge.net/p/open-cobol/code/HEAD/tree/branches/gnu-cobol-2.0/ is the main branch.

A pre-release, with Report Writer module by Ron Norman is the feature leading development source.

The next official releases will be from the GnuCOBOL 2.0 branch. This is the branch that has the most complete continuity of Roger While’s compiler developments.

Making the choice:

These are all good compilers. Until you are preparing for production rollouts, don’t worry too much about which version of the sources you use to build up applications. GnuCOBOL COBOL is pretty much COBOL, and these versions vary more in implementation details than anything else. Porting between versions will likely be zero effort, beyond verification.

For COBOL 85 with a little 2002, GnuCOBOL 1.1 is still a very valid choice.

For User Defined Functions, Report Writer, C++ emitter, IEEE FLOAT, then 2.0 is the better starting point. Slightly more risk, worthy of extra testing and analysis before committing to production use, until such time that there is a release announcement.

Even older versions:

OpenCOBOL 1.0 was released December 27th, 2007 by Roger While [Roger].

The decision to go 1.0 from the 0.33 version followed many incremental enhancements from 2005 through till late in 2007.

OpenCOBOL 1.1 pre-release became active on December 27th, 2007 and major developments occurred publicly until February, 2009. The pre-release source tar can be found at GnuCOBOL 1.1 with installer instructions at GnuCOBOL Install and in the INSTALLING text file of the sources.

The 1.1 pre-release of February 2009 was tagged as release on SourceForge in May of 2012. The 1.1 community edition is now in development as the 2.0 branch at http://sourceforge.net/projects/open-cobol

Newer versions:

GnuCOBOL with Report Writer will be mainline trunk as of early 2015. Later edit: Late 2015? Even still, the pre-release reportwriter SVN branch is sweet code, works great. Feature packed, Ron is doing world class work.

2.0 is the lead branch at this point. It’ll be released first.

2.4.1   Building the 1.1 stable version

After a download and extract from http://sourceforge.net/projects/open-cobol/files/latest/download?source=files

$ tar xvf gnu-cobol-1.1.tar.gz
$ cd gnu-cobol-1.1
$ ./configure
$ make
$ make check
$ sudo make install
$ sudo ldconfig

will place a new set of binaries in /usr/local, ready to roll.

The ldconfig after make install is important, GnuCOBOL installs shared libraries, and the link loader cache needs to be informed.

Be sure to see What are the configure options available for building GnuCOBOL? for all the available options for building from sources.

The above instructions also apply to the GnuCOBOL 2.0 release candidates.

2.4.2   Building GnuCOBOL 2.0 release candidates

Get a copy of the latest source kit from SourceForge

https://sourceforge.net/projects/open-cobol/files/gnu-cobol/2.0/gnu-cobol-2.0_rc-2.tar.gz/download

or

https://sourceforge.net/projects/open-cobol/files/gnu-cobol/2.0/gnu-cobol-2.0_rc-2_win.zip/download

Prerequisites include GMP, ncurses, Berkeley DB (or VB-ISAM) and the GNU build tools (gcc and friends), or other C compiler suite.

$ tar xvf gnu-cobol-2.0_rc-2.tar.gz
$ cd gnu-cobol-2.0
$ ./configure
$ make
$ make check
$ make test
$ sudo make install
$ sudo ldconfig

Use ./configure --help to list all of the available build configuration options.

make check does almost 700 internal tests, and make test runs a freshly built compiler with the NIST COBOL-85 test suite. These are important steps (make check in particular) and should pass before any make install.

If there are problems, visit the SourceForge Help getting started forum and experts will help you work out any local installation issues.

https://sourceforge.net/p/open-cobol/discussion/help/

2.4.3   occurlrefresh

If you build a pre-release OC1.1 or GnuCOBOL 2.0 and have libcurl, you will be able to compile the occurlrefresh.cbl (with occurlsym.cpy) application and an early occurl.c libCURL wrapper that allows file transfers off the internet. occurlrefresh includes default filenames for retrieving the most recent pre-release source archive and only updates the local copy if there has been a newer upstream release.

Thanks to [aoirthoir] for hosting these; currently (January 2017) at

and then simply

$ ./occurlrefresh

to download any new development archives. libCURL tests the modification timestamps, so this procedure is very resource efficient, only pulling from the server if there is something new. A -b option is accepted that will spawn off tar, configure and the make pass to compile a fresh copy. -b does not do an install, you’ll still have to do that manually after verifying that everything is ok.

2.4.4   Building the reportwriter version

Get the source

$ svn checkout svn://svn.code.sf.net/p/open-cobol/code/branches/reportwriter \
  gnu-cobol-rw
$ cd gnu-cobol-rw/

or with wget, thanks to Simon for the snippet.

$ mkdir reportwriter
$ wget -N -e robots=off -r -np -nH --cut-dirs =5 \
  http://svn.code.sf.net/p/open-cobol/code/branches/reportwriter
$ chmod 775 configure tests/testsuite
$ touch cobc/*pars*.c* cobc/pplex.c* cobc/scanner.c* cobc/*.hpp tests/testsuite

Set up for an out of tree build. Not necessary, but cleaner.

$ mkdir build
$ cd build
$ ../configure --help   # to see any options you may want to tweak
$ ../configure          # note the .. up directory, while in build/

and the make, test, and install

$ make
$ make check
$ sudo make install
$ sudo ldconfig

and for more validation, the NIST COBOL 85 test suite

$ cd tests/cobol85
$ wget http://www.itl.nist.gov/div897/ctg/suites/newcob.val.Z
$ uncompress newcob.val.Z
$ make test

Party, big party. Dancing, and woo hoos, like it’s 1985. Actually, the last test suite update was in 1993, shortly after Instrinsic Functions.

While the test is running, take a look at REPORT.

Or, read through some of the NIST test code, perhaps SM/SM101A.CBL, a program that puts COPY through its paces. Please note that newcob.val is not for redistribution. Get it from the source, and share the link, not the file.

2.5   What is the future of COBOL?

That is a good question. What follows is strictly opinion, and readers are encouraged to make the future and not wait for it to just happen.

COBOL is still very much in use with large systems, and big iron COBOL is a big business, all on its own. Millions are spent setting up and maintaining COBOL development systems. Many millions. That can be seen as a good thing, a bad thing, or a neutral thing. Some people are deeply invested in COBOL and see change as anathema. Some people are itching to get away from what they see as a money pit, stagnant as the world progresses. Some may be suffering internal conflict, split by both those extreme views.

Reality is likely somewhere in the middle. And part of the opinion, this author leans to staying with COBOL unless there are some serious reasons not to. User interface, interoperability and networking portions of hertitage applications come to mind. With GnuCOBOL, staying with COBOL may be a more attractive option. Source codes may need only minimal change, the money pit shrinks considerably, and at the same time interoperability potentials may increase, considerably. Keep all the heritage COBOL, extend into the future and build up, not sideways.

COBOL 2014 has some very nice features. Not all the features a modern development team may want or need, networking and user interface come to mind again, but a very solid core for problem solving. GnuCOBOL being a trans-compiler heavily rooted in C (or C++, thanks to Sergey), bridges the business computing model enshrined in COBOL, with the computer sciences enshrined in just about all the other programming development systems in use today. There are C implementations of nearly all mainstream programming languages. Java is actually based on a C implementation, as is Python, Perl, Ruby, PHP, to name but a few. There are C implementations of Ada, Fortran, BASIC, Lisp, Prolog, Javascript, a very long list. COBOL is a first class citizen in all of these environments with GnuCOBOL. GnuCOBOL bridges the gap between Business and Science, and can take on either role, fully, or in a mixed paradigm.

Need a network module? CALL it, or use cobc to link object code directly into a master program. Need a slicker user interface, use cobweb-gtk or cobweb-tk and offer up modern screens. CALL a few other modules and have a browser ready interface. Need the flexibility of some advanced data structure or multiprocessing system? Link it in. Need the Cloud? Put an instance of GnuCOBOL on your Cloud. Need a DevOps strategy, well, build that layer around heritage and let your GnuCOBOL developers talk with your GnuCOBOL operations teams. Need to interoperate with some monster third party system? Dig in, knowing full well that it’ll work at the common layer of the C application binary interface.

The future of COBOL is what we will make of it. High costs no longer needs to be the primary area of modernization discussions surrounding heritage COBOL systems. They can be, for those that feel the need to spend; and there will be vendors willing to sign you up, for decades to come. Or, for those willing, GnuCOBOL will be waiting to ease some of the financial burdens, and open up the future to the opportunities that await.

3   Using GnuCOBOL

3.1   How do I install GnuCOBOL?

Installation instructions can be found at GnuCOBOL Install, but there are now a few ways to install GnuCOBOL.

3.1.1   From source with GNU/Linux

$ wget http://sourceforge.net/projects/open-cobol/files/gnu-cobol/1.1/gnu-cobol-1.1.tar.gz
$ tar xvf gnu-cobol-1.1.tar.gz
$ cd gnu-cobol-1.1
$ ./configure
$ make
$ make check
$ sudo make install
$ sudo ldconfig

January 2015:

A note on versions. OpenCOBOL 1.1 Feb 2009 was the last public pre-release of what is now GnuCOBOL.

There were two rebranding passes. OpenCOBOL to GNU Cobol then to GnuCOBOL. GNU Cobol 1.1 is the package listed here. It is OpenCOBOL 1.1 with rebranding, and a fair number of bug fixes and improvements.

Alternatively, for later, more feature rich, but less tested GnuCOBOL 2, change the wget to:

wget -N -e robots=off -r -np -nH --cut-dirs =5 \
    http://svn.code.sf.net/p/open-cobol/code/branches/gnu-cobol-2.0

for the master development branch. Or, Report Writer. Close to 2.0, but diverged earlier, at a point that will require a merge into master.

wget -N -e robots=off -r -np -nH --cut-dirs =5 \
    http://svn.code.sf.net/p/open-cobol/code/branches/reportwriter

or for a C++ version, again, an earlier 2.0 branch point:

wget -N -e robots=off -r -np -nH --cut-dirs =5 \
    http://svn.code.sf.net/p/open-cobol/code/branches/gnu-cobol-cpp

or:

wget -N -e robots=off -r -np -nH --cut-dirs =5 \
    http://svn.code.sf.net/p/open-cobol/code/branches/fileiorewrite

The backslashes represent an ignored newline. If you combine the lines, drop the backslash. It is only there for width control, the wget command is all one line.

Reportwriter will be folded into 2.0, fileiorewrite is a fileio.c rewrite, and will be merged into master, as well. The C++ version is close to baseline. gnu-cobol-cpp will remain a separate branch for the forseeable future.

If you are reading this for the first time, and looking for a COBOL 85 compiler, go with the initial gnu-cobol-1.1 instructions. All these compilers are valid, working COBOL compilers. But gnu-cobol-1.1 (which is very close to open-cobol-1.1, the version in most major distros) is very likely the most common installation type, by far. Years and years of accumulated installs.

GnuCOBOL 2.0 is close to ready, but not stamped for production by the development team quite yet. It too is a valid COBOL compiler, passing over 9700 NIST tests, but, production use would come with warnings to include an extra round of verification and site suitability testing.

For anyone that needs to care, 1.1 is GPL (and LGPL) 2+, newer cuts are GPL (and LGPL) 3+.

Please see What are the differences between OpenCOBOL 1.1 and GnuCOBOL 1.1?

3.1.2   Debian

The Debian binary package makes installing GnuCOBOL 1.0 a snap. From root or using sudo

$ apt-get install open-cobol

3.1.3   Ubuntu

The Ubuntu repositoies are very similar to Debian, using the same APT tool set.

Note on linking: Please be aware that Ubuntu has made a change to default link optimization that currently REQUIRE an external setting for the proper use of GnuCOBOL (and the older named OpenCOBOL) with dynamic libraries.

export COB_LD_FLAGS='-Wl, --no-as-needed'

before any compiles that use -l (minus ell) options to include named libraries.

See Why can’t libcob find my link modules at run-time? for further details.

3.1.4   Fedora

From the main Fedora repositories

$ yum install open-cobol

3.1.5   Windows

And then we get to Windows™. A lot of people seem to have trouble with getting GnuCOBOL up and running with Windows. This situation has steadily improved since 2009, and continues to improve as of 2015.

First, builds can be from sources using Cygwin or MinGW. These two extensions to Windows provide a necessary layer of POSIX features that GnuCOBOL was created with (and for).

With Cygwin, you can simply follow the instructions listed above for building on GNU/Linux. Cygwin provides almost all of the same tools.

For MinGW, read the OC_GettingStarted_Windows document by [wmklein] available online at

Also see What is the current version of GnuCOBOL? and visual studio.

One recent addition for easing the burden with Windows installs came from Arnold Trembley. He put together an amalgam of intstructions and code to create a bundle that when extracted should have you up and running with a MinGW GnuCOBOL system in a very short period of time.

From Arnold:

I worked with Realia COBOL 4.2 for OS/2 and DOS back in the early 1990's.
It was an excellent compiler, but too expensive for me to buy for personal
use.  Unlike Microfocus COBOL, there were no license fees for executables
you created using Realia COBOL. CA (formerly Computer Associates) bought
Realia, and I don't think CA-Realia COBOL is available any more.

Two days was just for me to fumble around with building the GnuCOBOL 2.0
from source, while writing a manual (still unfinished) on how to do it. My
end goal is to create an installer for the GnuCOBOL 2.0 (like I did for
GnuCOBOL 1.1) so you can run a setup.exe for it like any other windows
application. But if GC 2.0 will be included in a future release of
OpenCOBOLIDE that would be even better.

I have a working version of GnuCOBOL 2.0 (r624 from 10JUL2015) built with
MinGW, if you would like to try it, but it's a 52 megabyte zip file with
no documentation or installer. You can download it from here:

http://www.arnoldtrembley.com/GC20base.zip

Create a folder named something like c:\GnuCOBOL or C:\GC20 and unzip the
contents into it while preserving the directory structure. Read the CMD
files for an idea of how to setup the environment variables. Several
months ago I tested it with OpenCOBOLIDE, and I was able to compile a
small COBOL program.

And from a happy customer (Eugenio Di Lorenzo) that just wanted to get GnuCOBOL installed with a minimum of fuss:

Good Job Arnold. This is what I need.

Just downloaded, unpacked and it works out of the box !  1 minute for
installation.  After that I configured preferences in OCIDE and all works
fine.  Thanks a lot.

I suggest to store this zip file or something similar into the sourceforge
site.

Following Eugenio’s advice, a home for Arnold’s works will be in the GnuCOBOL project space at:

http://open-cobol.sourceforge.net/files/index.html

3.1.6   Macintosh

From Ganymede on opencobol.org

HOWTO: Installling OpenCOBOL 1.0.0 (with BerkeleyDB) under Mac OS 10.5.x-10.6.x

On Mac OS X 10.5.x/10.6.x, I have successfully managed to compile and install
OpenCOBOL 1.0.0 (including libdb linking), and am now happily compiling
production systems with it. It's not *entirely* straightforward, as it involves
installing GMP via MacPorts -- the *only way* that GMP will install properly
because of some eccentricities in Apple's Xcode development tools (particularly
with relation to c99 in gcc), unless you are willing to patch things by hand.
In addition, the earlier BerkeleyDB versions (the 4.x.x ones available via
MacPorts) cause some strange ioctl errors at runtime under Mac OS X Leopard and
Snow Leopard when attempting certain types of ORGANIZATION IS INDEXED
operations; precisely what conditions causes this I am yet to fully ascertain.
The upshot of it is that in order to compile and run a complete OpenCOBOL 1.0.0
installation on Leopard and Snow Leopard, one has to 1) install GMP via
MacPorts; but 2) compile and install a recent version of BerkeleyDB natively.

Probably at some point, I'm going to package this into a pretty-pretty
precompiled .app and .dmg along with a rudimentary Cocoa compiler interface.
Until then, however -- my COBOL on Mac comrades! -- please do the following:

-- INSTALLATION STEPS (Tested on both 10.5.x and 10.6.x) --
1) Download an appropriate MacPorts distribution for your OS:
<http://distfiles.macports.org/MacPorts/>
If you want to use the installer:
* For 10.5.x: MacPorts-1.8.0-10.5-Leopard.dmg
* For 10.6.x: MacPorts-1.8.0-10.6-SnowLeopard.dmg
From source, MacPorts-1.8.0.tar.gz is confirmed to work on both versions.
NB: Make sure PATH is properly set by install in your active user's ~/.profile.
2) Update MacPorts: sudo port -d selfupdate
3) Install GMP with MacPorts: sudo port install gmp
4) Download the Oracle Berkeley DB 5.0.21 (or later) .tar.gz source:
<http://www.oracle.com/technology/products/berkeley-db/db/index.html>
5) Untar, cd to the Berkeley DB source folder, then:
cd /build_unix
6) Do the following to configure, make and install Berkeley DB:
../dist/configure
make
sudo make install
7) Download and untar OpenCOBOL 1.0.0, cd to directory
8) Run ./configure, setting CPPFLAGS and LDFLAGS as below (CHANGING ANY
VERSION-SPECIFIC PATHS TO WHAT YOU JUST INSTALLED) as follows:

./configure
CPPFLAGS="-I/opt/local/var/macports/software/gmp/5.0.1_0/opt/local/include/
-I/usr/local/BerkeleyDB.5.0/include/"
LDFLAGS="-L/opt/local/var/macports/software/gmp/5.0.1_0/opt/local/lib
-L/usr/local/BerkeleyDB.5.0/lib/"

9) Make and install:
make
sudo make install
10) Et voila! Try exiting the directory and invoking cobc.

-- YOU SHOULD THEN BE ABLE TO DO SOMETHING LIKE THIS: --

phrygia.ganymede-labs.com:bottles ganymede$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.5.6
BuildVersion: 9G55
phrygia.ganymede-labs.com:bottles ganymede$ cobc -V
cobc (OpenCOBOL) 1.0.0
Copyright (C) 2001-2007 Keisuke Nishida
Copyright (C) 2007 Roger While
phrygia.ganymede-labs.com:bottles ganymede$ cobc -v -x bottles.cbl
preprocessing bottles.cbl into
/var/folders/KI/KI15WC0KGMmvvO980RztgU+++TI/-Tmp-//cob75450_0.cob translating
/var/folders/KI/KI15WC0KGMmvvO980RztgU+++TI/-Tmp-//cob75450_0.cob into
/var/folders/KI/KI15WC0KGMmvvO980RztgU+++TI/-Tmp-//cob75450_0.c
  gcc -pipe -c -I/usr/local/include
-I/opt/local/var/macports/software/gmp/5.0.1_0/opt/local/include/
-I/usr/local/BerkeleyDB.5.0/include/ -I/usr/local/include -O2 -Wno-unused
-fsigned-char -Wno-pointer-sign -o
/var/folders/KI/KI15WC0KGMmvvO980RztgU+++TI/-Tmp-//cob75450_0.o
/var/folders/KI/KI15WC0KGMmvvO980RztgU+++TI/-Tmp-//cob75450_0.c gcc -pipe
-L/opt/local/var/macports/software/gmp/5.0.1_0/opt/local/lib
-L/usr/local/BerkeleyDB.5.0/lib/ -o bottles
/var/folders/KI/KI15WC0KGMmvvO980RztgU+++TI/-Tmp-//cob75450_0.o
-L/opt/local/var/macports/software/gmp/5.0.1_0/opt/local/lib
-L/usr/local/BerkeleyDB.5.0/lib/ -L/usr/local/lib -lcob -lm -lgmp
-L/usr/local/lib -lintl -liconv -lc -R/usr/local/lib -lncurses -ldb


With lots of sloppy LINKAGE SECTION kisses,
-- Ganymede

3.1.6.1   homebrew

And an update from Martin Ward. This is likely how GnuCOBOL 2 compile from source efforts should be approached in 2015 and beyond. Martin needed 32 bit pointers, and struggled through to come up with a homebrew solution to his GnuCOBOL build.

I tried brew install gnu-cobol --universal but that just installs the
64 bit version. I would prefer to compile from source: which means
installing 32 bit versions of libdb and gmp.  brew install gmp --32-bit
will install a 32 bit version of gmp, but this option does not affect the
installation of libdb.

I compiled db-6.1.26 with CFLAGS=-m32 and installed it, and then built
GnuCOBOL with: ./configure CFLAGS=-m32
CPPFLAGS=-I/usr/local/BerkeleyDB.6.1/include/
LDFLAGS=-L/usr/local/BerkeleyDB.6.1/lib/

This works!

3.1.7   CentOS

From the discussion forum on SourceForge, by Stuart Bishop.

Just to document this a little further as I've got this install down pat and
repeated many times - to do an install of Opencobol-1.1 on a newly installed
Centos-6.6:

After installing a "Basic Server" Centos-6.6 from CD 1 of 2…

Login to your CentOS Box, and su to root

install dependencies 1 of 2
yum install gmp gmp-devel libtool ncurses ncurses-devel ncurses-libs make

install dependencies 2 of 2
yum install libdbi libdbi-devel libtool-ltdl libtool-ltdl-devel db4 db4-devel

Obtain gmp-5.1.3.tar; ./configure; make; make check; make install

Download open-cobol 1.1.tar.gz; you can use wget
yum install wget
wget http://downloads.sourceforge.net/project/open-cobol/
Copy to say /usr/local and decompress and extract

cd /usr/local/open-cobol-1.1

Build and install with ./configure; make; make check; make install

But, GnuCOBOL has some nice fixes, as it was being rebranded from OpenCOBOL.

The wget might be better as

$ wget http://sourceforge.net/projects/open-cobol/files/gnu-cobol/1.1/gnu-cobol-1.1.tar.gz
 ...
$ cd ...gnu-cobol-1.1
 ...

or one of the others, listed above; reportwriter, C++, fileio rewrite, 2.0; Go with the 2.0 pre-releases, it’s the master branch, and reportwriter, for very well done REPORT SECTION support. Passes NIST suport tests, and most report code thrown at it, say back to 68. Almost 50 years of backwards compatibility and a chance to revitalize COBOL assets, perhaps thought lost to price / value ratios for run-time fees versus perceived value for some older report layouts.

3.2   What are the configure options available for building GnuCOBOL?

configure is a de facto standard development tool for POSIX compliant operating systems, in particular GNU/Linux. It examines the current environment and creates a Makefile suitable for the target computer and the package being built.

For GnuCOBOL, the ./configure script accepts --help as a command line option to display all of the available configuration choices.

`configure' configures GnuCOBOL 1.1 to adapt to many kinds of systems.

Usage: ./configure [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

Configuration:
  -h, --help              display this help and exit
      --help=short        display options specific to this package
      --help=recursive    display the short help of all the included packages
  -V, --version           display version information and exit
  ---quiet, --silent   do not print `checking...' messages
      --cache-file=FILE   cache test results in FILE [disabled]
  -C, --config-cache      alias for `--cache-file=config.cache'
  -n, --no-create         do not create output files
      --srcdir=DIR        find the sources in DIR [configure dir or `..']

Installation directories:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [/usr/local]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [PREFIX]

By default, `make install' will install all the files in
`/usr/local/bin', `/usr/local/lib' etc.  You can specify
an installation prefix other than `/usr/local' using `--prefix',
for instance `--prefix=$HOME'.

For better control, use the options below.

Fine tuning of the installation directories:
  --bindir=DIR           user executables [EPREFIX/bin]
  --sbindir=DIR          system admin executables [EPREFIX/sbin]
  --libexecdir=DIR       program executables [EPREFIX/libexec]
  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
  --libdir=DIR           object code libraries [EPREFIX/lib]
  --includedir=DIR       C header files [PREFIX/include]
  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
  --infodir=DIR          info documentation [PREFIX/info]
  --mandir=DIR           man documentation [PREFIX/man]

Program names:
  --program-prefix=PREFIX            prepend PREFIX to installed program names
  --program-suffix=SUFFIX            append SUFFIX to installed program names
  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names

System types:
  --build=BUILD     configure for building on BUILD [guessed]
  --host=HOST       cross-compile to build programs to run on HOST [BUILD]

Optional Features:
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --enable-maintainer-mode  enable make rules and dependencies not useful
                          (and sometimes confusing) to the casual installer
  --disable-dependency-tracking  speeds up one-time build
  --enable-dependency-tracking   do not reject slow dependency extractors
  --enable-experimental   (GnuCOBOL) enable experimental code (Developers only!)
  --enable-param-check    (GnuCOBOL) enable CALL parameter checking
  --enable-shared[=PKGS]
                          build shared libraries [default=yes]
  --enable-static[=PKGS]
                          build static libraries [default=yes]
  --enable-fast-install[=PKGS]
                          optimize for fast installation [default=yes]
  --disable-libtool-lock  avoid locking (might break parallel builds)
  --disable-rpath         do not hardcode runtime library paths
  --disable-nls           do not use Native Language Support

Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-cc=<cc>          (GnuCOBOL) specify the C compiler used by cobc
  --with-seqra-extfh      (GnuCOBOL) Use external SEQ/RAN file handler
  --with-cisam            (GnuCOBOL) Use CISAM for ISAM I/O
  --with-disam            (GnuCOBOL) Use DISAM for ISAM I/O
  --with-vbisam           (GnuCOBOL) Use VBISAM for ISAM I/O
  --with-index-extfh      (GnuCOBOL) Use external ISAM file handler
  --with-db1              (GnuCOBOL) use Berkeley DB 1.85 (libdb-1.85)
  --with-db               (GnuCOBOL) use Berkeley DB 3.0 or later (libdb)(default)
  --with-lfs64            (GnuCOBOL) use large file system for file I/O (default)
  --with-dl               (GnuCOBOL) use system dynamic loader (default)
  --with-patch-level      (GnuCOBOL) define a patch level (default 0)
  --with-varse         (GnuCOBOL) define variable sequential format (default 0)
  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
  --with-pic              try to use only PIC/non-PIC objects [default=use
                          both]
  --with-tags[=TAGS]
                          include additional configurations [automatic]
  --with-gnu-ld           assume the C compiler uses GNU ld default=no
  --with-libiconv-prefix[=DIR]  search for libiconv in DIR/include and DIR/lib
  --without-libiconv-prefix     don't search for libiconv in includedir and libdir
  --with-libintl-prefix[=DIR]  search for libintl in DIR/include and DIR/lib
  --without-libintl-prefix     don't search for libintl in includedir and libdir

Some influential environment variables:
  CC          C compiler command
  CFLAGS      C compiler flags
  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
              nonstandard directory <lib dir>
  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
              headers in a nonstandard directory <include dir>
  CPP         C preprocessor
  CXXCPP      C++ preprocessor

Use these variables to override the choices made by 'configure' or to help
it to find libraries and programs with nonstandard names/locations.

Report bugs to <open-cobol-list@lists.sourceforge.net>.

3.2.1   GnuCOBOL build time environment variables

LD_RUN_PATH
Embeds build time library paths in the compiler. Handy when on hosts without root access. Point cobc at user built libcob and dependency libraries when needed. If set while compiling as well, CGI binaries will know where to find libcob and any other custom DSO files.
LD_LIBRARY_PATH
Run time shared library path, can effect lookup order during ./configure, make, but mentioned here as an alternative to LD_RUN_PATH. Complicating factor when running GnuCOBOL CGI on shared hosts. An intermediate script is needed to set LD_LIBRARY_PATH to point to local user account libcob. (Or hint to staff to install GnuCOBOL, very likely (as of 2014) in repositories as open-cobol. Some package maintainers have separated the GPL compiler and LGPL run-time support into open-cobol and libcob1 (along with -dev header packages for both).
COB_CC
The C compiler invoked during the cobc build chain.
COB_CFLAGS
The flags passed to the C compiler during the build chain.
COB_LDFLAGS
The link flags pass to the C compiler.
COB_LIBS
The default -l libraries used during the C compiler phase. -lm -lcob etcetera. These commands and options are displayed with cobc -v.
COB_CONFIG_DIR
Hmm, news says this was dropped, but it’ll effect where .conf dialect support files are found.
COB_COPY_DIR
Path to COPY books.
COBCPY
Path to COPY books. Knowing Roger these are cumulative.
COB_LIBRARY_PATH
Sets a default.
COB_VARSEQ_FORMAT
Determines a few code paths during make.
COB_UNIX_LF
Sets a default.

3.3   Does GnuCOBOL have any other dependencies?

GnuCOBOL relies on a native C compiler with POSIX compatibility. GCC being a freely available compiler collection supported by most operating systems currently (January 2017) in use.

GnuCOBOL requires the following external libraries to be installed:

GNU MP (libgmp) 4.1.2 or later
libgmp is used to implement decimal arithmetic. GNU MP is licensed under GNU Lesser General Public License.
GNU Libtool (libltdl)
libltdl is used to implement dynamic CALL statements. GNU Libtool is licensed under GNU Lesser General Public License.

NOTE - Libtool is not required for Linux and Windows (including MinGW and Cygwin)

The following libraries are optional:

Berkeley DB (libdb) 1.85 or later

libdb can be used to implement indexed file I/O and SORT/MERGE. Berkeley DB is licensed under the original BSD License (1.85) or their own open-source license (2.x or later). Note that, as of 2.x, if you linked your software with Berkeley DB, you must distribute the source code of your software along with your software, or you have to strike a deal with Oracle Corporation.

For more information about Oracle Berkeley DB dual licensing see:

http://www.oracle.com/technetwork/database/berkeleydb/downloads/licensing-098979.html

Ncurses (libncurses) 5.2 or later
libncurses can be used to implement SCREEN SECTION. Ncurses is licensed under a BSD-style license.

3.4   How does the GnuCOBOL compiler work?

GnuCOBOL is a multi-stage command line driven compiler. Command line options control what stages are performed during processing.

  1. Preprocess
  2. Translate
  3. Compile
  4. Assemble
  5. Link
  6. Build

GnuCOBOL produces intermediate C source code that is then passed to a configured C compiler and other tools. the GNU C compiler, gcc being a standard.

The main tool, cobc, by default, produces modules, linkable shared object files. Use cobc -x to produce executables (with a main).

3.4.1   Example of GnuCOBOL stages

Documenting the output of the various stages of GnuCOBOL compilation.

3.4.2   Original source code

hello.cob

000100* HELLO.COB GnuCOBOL FAQ example
000200 IDENTIFICATION DIVISION.
000300 PROGRAM-ID. hello.
000400 PROCEDURE DIVISION.
000500     DISPLAY "Hello, world".
000600     STOP RUN.

3.4.3   Preprocess

$ cobc -E hello.cob

Preprocess only pass. One operation of the preprocessor is to convert FIXED format to FREE format. COPY includes are also read in along with REPLACE substitution. The above command displayed:

# 1 "hello.cob"

IDENTIFICATION DIVISION.
PROGRAM-ID. hello.
PROCEDURE DIVISION.
 DISPLAY "Hello, world".
 STOP RUN.

to standard out.

3.4.4   Translate

$ cobc -C hello.cob

Translate only; preprocesses and then translates the COBOL sources into C. You can examine these files to get a good sense of how the GnuCOBOL environment interacts with the native C facilities. GnuCOBOL 1.1 produced hello.c.h and hello.c.

3.4.5   hello.c.h

/* Generated by            cobc 1.1.0 */
/* Generated from          hello.cob */
/* Generated at            Oct 04 2008 00:19:36 EDT */
/* GnuCOBOL build date    Oct 01 2008 22:15:19 */
/* GnuCOBOL package date  Oct 01 2008 16:31:26 CEST */
/* Compile command         cobc -C hello.cob */

/* PROGRAM-ID : hello */

static unsigned char b_5[4] __attribute__((aligned));        /* COB-CRT-STATUS */
static unsigned char b_1[4] __attribute__((aligned));        /* RETURN-CODE */
static unsigned char b_2[4] __attribute__((aligned));        /* SORT-RETURN */
static unsigned char b_3[4] __attribute__((aligned));        /* NUMBER-OF-CALL-PARAMETERS */

/* attributes */
static cob_field_attr a_1        = {16, 4, 0, 0, NULL};
static cob_field_attr a_2        = {33, 0, 0, 0, NULL};

/* fields */
static cob_field f_5        = {4, b_5, &a_1};        /* COB-CRT-STATUS */

/* constants */
static cob_field c_1        = {12, (unsigned char *)"Hello, world", &a_2};

/* ---------------------------------------------- */

3.4.6   hello.c

/* Generated by            cobc 1.1.0 */
/* Generated from          hello.cob */
/* Generated at            Oct 04 2008 00:19:36 EDT */
/* GnuCOBOL build date    Oct 01 2008 22:15:19 */
/* GnuCOBOL package date  Oct 01 2008 16:31:26 CEST */
/* Compile command         cobc -C hello.cob */

#define  __USE_STRING_INLINES 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <libcob.h>

#define COB_SOURCE_FILE                "hello.cob"
#define COB_PACKAGE_VERSION        "1.1"
#define COB_PATCH_LEVEL                0

/* function prototypes */
static int hello_ (const int);

int hello (void);


/* functions */

int
hello ()
{
  return hello_ (0);
}

/* end functions */

static int
hello_ (const int entry)
{

#include "hello.c.h"  /* local variables */

  static int initialized = 0;
  static cob_field *cob_user_parameters[COB_MAX_FIELD_PARAMS];
  static cob_module module = { NULL, NULL, &f_5, NULL, cob_user_parameters, 0, '.',
                               '$', ',', 1, 1, 1, 0};


  /* perform frame stack */
  int frame_index;
  struct frame {
    int  perform_through;
    void *return_address;
  } frame_stack[255];

  /* Start of function code */

  if (unlikely(entry < 0)) {
    if (!initialized) {
        return 0;
    }
    initialized = 0;
    return 0;
  }

  module.next = cob_current_module;
  cob_current_module = &module;

  if (unlikely(initialized == 0))
    {
      if (!cob_initialized) {
        cob_fatal_error (COB_FERROR_INITIALIZED);
      }
      cob_check_version (COB_SOURCE_FILE, COB_PACKAGE_VERSION, COB_PATCH_LEVEL);
      if (module.next)
        cob_set_cancel ((const char *)"hello", (void *)hello, (void *)hello_);
      (*(int *) (b_1)) = 0;
      (*(int *) (b_2)) = 0;
      (*(int *) (b_3)) = 0;
      memset (b_5, 48, 4);


      initialized = 1;
    }

  /* initialize frame stack */
  frame_index = 0;
  frame_stack[0].perform_through = -1;

  /* initialize number of call params */
  (*(int *) (b_3))   = cob_call_params;
  cob_save_call_params = cob_call_params;

  goto l_2;

  /* PROCEDURE DIVISION */


  /* hello: */

  l_2:;

  /* MAIN SECTION: */

  /* MAIN PARAGRAPH: */

  /* hello.cob:5: DISPLAY */
  {
    cob_new_display (0, 1, 1, &c_1);
  }
  /* hello.cob:6: STOP */
  {
    cob_stop_run ((*(int *) (b_1)));
  }

  cob_current_module = cob_current_module->next;
  return (*(int *) (b_1));

}

/* end function stuff */

3.4.7   Generate assembler

Using the -S switch asks cobc to ask the C compiler tool chain to not process farther than the assembler code generation phase.

$ cobc -S hello.cob

3.4.8   hello.s

    .file        "cob9141_0.c"
    .text
.globl hello
    .type        hello, @function
hello:
    pushl        %ebp
    movl        %esp, %ebp
    subl        $8, %esp
    movl        $0, (%esp)
    call        hello_
    leave
    ret
    .size        hello, .-hello
    .data
    .align 4
    .type        module.5786, @object
    .size        module.5786, 28
module.5786:
    .long        0
    .long        0
    .long        f_5.5782
    .long        0
    .long        cob_user_parameters.5785
    .byte        0
    .byte        46
    .byte        36
    .byte        44
    .byte        1
    .byte        1
    .byte        1
    .byte        0
    .local        cob_user_parameters.5785
    .comm        cob_user_parameters.5785,256,32
    .local        initialized.5784
    .comm        initialized.5784,4,4
    .section        .rodata
.LC0:
    .string        "Hello, world"
    .data
    .align 4
    .type        c_1.5783, @object
    .size        c_1.5783, 12
c_1.5783:
    .long        12
    .long        .LC0
    .long        a_2.5781
    .align 4
    .type        f_5.5782, @object
    .size        f_5.5782, 12
f_5.5782:
    .long        4
    .long        b_5.5776
    .long        a_1.5780
    .align 4
    .type        a_2.5781, @object
    .size        a_2.5781, 8
a_2.5781:
    .byte        33
    .byte        0
    .byte        0
    .byte        0
    .long        0
    .align 4
    .type        a_1.5780, @object
    .size        a_1.5780, 8
a_1.5780:
    .byte        16
    .byte        4
    .byte        0
    .byte        0
    .long        0
    .local        b_3.5779
    .comm        b_3.5779,4,16
    .local        b_2.5778
    .comm        b_2.5778,4,16
    .local        b_1.5777
    .comm        b_1.5777,4,16
    .local        b_5.5776
    .comm        b_5.5776,4,16
    .section        .rodata
.LC1:
    .string        "1.1"
.LC2:
    .string        "hello.cob"
.LC3:
    .string        "hello"
    .text
    .type        hello_, @function
hello_:
    pushl        %ebp
    movl        %esp, %ebp
    subl        $2072, %esp
    movl        8(%ebp), %eax
    shrl        $31, %eax
    testl        %eax, %eax
    je        .L4
    movl        initialized.5784, %eax
    testl        %eax, %eax
    jne        .L5
    movl        $0, -2052(%ebp)
    jmp        .L6
.L5:
    movl        $0, initialized.5784
    movl        $0, -2052(%ebp)
    jmp        .L6
.L4:
    movl        cob_current_module, %eax
    movl        %eax, module.5786
    movl        $module.5786, cob_current_module
    movl        initialized.5784, %eax
    testl        %eax, %eax
    sete        %al
    movzbl        %al, %eax
    testl        %eax, %eax
    je        .L7
    movl        cob_initialized, %eax
    testl        %eax, %eax
    jne        .L8
    movl        $0, (%esp)
    call        cob_fatal_error
.L8:
    movl        $0, 8(%esp)
    movl        $.LC1, 4(%esp)
    movl        $.LC2, (%esp)
    call        cob_check_version
    movl        module.5786, %eax
    testl        %eax, %eax
    je        .L9
    movl        $hello_, 8(%esp)
    movl        $hello, 4(%esp)
    movl        $.LC3, (%esp)
    call        cob_set_cancel
.L9:
    movl        $b_1.5777, %eax
    movl        $0, (%eax)
    movl        $b_2.5778, %eax
    movl        $0, (%eax)
    movl        $b_3.5779, %eax
    movl        $0, (%eax)
    movl        $4, 8(%esp)
    movl        $48, 4(%esp)
    movl        $b_5.5776, (%esp)
    call        memset
    movl        $1, initialized.5784
.L7:
    movl        $0, -4(%ebp)
    movl        $-1, -2044(%ebp)
    movl        $b_3.5779, %edx
    movl        cob_call_params, %eax
    movl        %eax, (%edx)
    movl        cob_call_params, %eax
    movl        %eax, cob_save_call_params
.L10:
    movl        $c_1.5783, 12(%esp)
    movl        $1, 8(%esp)
    movl        $1, 4(%esp)
    movl        $0, (%esp)
    call        cob_new_display
    movl        $b_1.5777, %eax
    movl        (%eax), %eax
    movl        %eax, (%esp)
    call        cob_stop_run
.L6:
    movl        -2052(%ebp), %eax
    leave
    ret
    .size        hello_, .-hello_
    .ident        "GCC: (Debian 4.3.1-9) 4.3.1"
    .section        .note.GNU-stack,"",@progbits

Produces hello.s.

3.4.9   Produce object code

$ cobc -c hello.cob

Compile and assemble, do not link. Produces hello.o.

3.4.10   Build modules

$ cobc -m hello.cob

Build dynamically loadable module. The is the default behaviour. This example produces hello.so or hello.dll.

$ cobc -b hello.cob

-b also creates a DSO. In this simple case, the extended Build is the same as the single Module build with -m. -b will build a dynamically loadable module that includes all the entry points from all of the files included on a command line. It’s fun; you can mix .cob, .c, , .s, .o, and -l libs and GnuCOBOL does the right thing glueing it all together. -b Build together is eminently suited to Programming In The Large and using cobcrun.

$ cobc -b hello.cob support.c

will put together a single DSO that includes all the functions from support.c, as well as the entry points defined in hello.cob.

$ cobc -m hello.cob support.c

will create two separate DSO files, one for hello and one for support.

3.4.11   Module run

$ cobcrun hello
Hello, world

Will scan the DSO hello.so, and then link, load, and execute hello.

3.4.12   Create executable

$ cobc -x hello.cob

Create an executable program. This examples produces hello or hello.exe.

Important:. cobc produces a Dynamic Shared Object by default. To create executables, you need to use -x.

$ ./hello
Hello, world

GnuCOBOL also supports features for multiple source, multiple language programming, detailed in the FAQ at Does GnuCOBOL support modules?.

3.4.13   Run job

There is an additional cobc switch in GnuCOBOL 2.0, -j that asks the compiler to execute the program (or module) after compilation.

$ cobc -xj hello.cob
Hello, world

The job switch allows GnuCOBOL programmers to follow a Compile, Link and Go development paradigm. -j will invoke cobcrun when -m or -b builds are requested.

3.4.14   Interpreter directive

It even goes one step further, using the power of hash-bang POSIX style shell interpreter directives. GnuCOBOL programs can be treated as scripts.

For example, given the text file, hello-cobol.sh

#!/usr/local/bin/cobc -xj
000100* HELLO.COB GnuCOBOL FAQ example
000200 IDENTIFICATION DIVISION.
000300 PROGRAM-ID. hello.
000400 PROCEDURE DIVISION.
000500     DISPLAY "Hello, world".
000600     STOP RUN.

with chmod +x hello-cobol.sh you get

$ ./hello-cobol.sh
Hello, world

Scripted COBOL. (Or at least it feels like it; the text passed to the interpreter, which is effectively cobc, is compiled (and executed) due to the -xj compiler switches).

3.4.15   sizes for hello on Fedora 16

The directory listing after using the various cobc options:

-rwxrwxr-x. 1 btiffin btiffin  9730 Apr 22 00:25 hello
-rw-rw-r--. 1 btiffin btiffin  2253 Apr 22 00:26 hello.c
-rw-rw-r--. 1 btiffin btiffin   835 Apr 22 00:26 hello.c.h
-rw-rw-r--. 1 btiffin btiffin   391 Apr 22 00:26 hello.c.l.h
-rw-rw-r--. 1 btiffin btiffin   181 Apr 22 00:24 hello.cob
-rw-rw-r--. 1 btiffin btiffin  3288 Apr 22 00:24 hello.o
-rw-rw-r--. 1 btiffin btiffin  2577 Apr 22 00:26 hello.s
-rwxrwxr-x. 1 btiffin btiffin  9334 Apr 22 00:27 hello.so

Not bad. Small programs, small native binaries. As things should be.

3.5   What is cobc?

cobc is the GnuCOBOL compiler. It processes source code into object, library or executable code. cobc can also produce listings, and/or cross-reference files. You can also ask cobc to leave intermediate generated C sources on disk for perusal or further processing.

See What compiler options are supported? for more information.

With most installations, man cobc and info cobc will be available anytime you need a little assistance when working with the compiler.

cobc --help is always available, and will display the many compile time options.

cobc --version will display build date and release version.

cobc --info will display various platform and configuration information.

To get a complete picture of your compile and runtime environments:

  • cobc --version
  • cobc --info
  • cobc --list-reserved
  • cobc --std=cobol2002 --list-reserved, shows word list for a given conf
  • cobc --list-intrinsics
  • cobc --list-mnemonics
  • cobc --list-system
  • cobcrun --version, (libcob and cobcrun versions)
  • cobcrun --info, (build info for libcob)
  • cobcrun --runtime-conf, will take into account any active overrides

3.6   What is cobcrun?

cobcrun is the GnuCOBOL driver program that allows the execution of programs stored in GnuCOBOL modules.

The cobc compiler, by default, produces modules (the -m option). These modules are linkable dynamic shared objects (DSO). Using GNU/Linux for example

$ cobc -x hello.cob
$ ./hello
Hello, world

$ cobc hello.cob
$ cobcrun hello
Hello, world

The cobc -x hello.cob built an executable binary called hello. The cobc hello.cob produced a DSO hello.so, and cobcrun resolves the entry point and executes the code, right from the DSO.

cobcrun is the compiler author’s preferred way to manage GnuCOBOL development. It alleviates knowing which source file needs -x while encouraging proper modular programming, a mainstay of GnuCOBOL.

There is a cobcrun command line switch, -M in GnuCOBOL 2.0 that offers even more flexibility when running modules.

It will preset COB_LIBRARY_PATH with any optional path and COB_PRE_LOAD with an optional module basename. Ending slash only sets path. -M will accept path/file, path/, or file.

# build up a library, lots of subprograms in a single DSO
cobc -b multiprog.cob program??.cob

# run program06 in library multiprog, with a single argc/argv string
cobcrun -M multiprog program06 "command line argument"

# equivalent to cobcrun multiprog, without -M, if CWD is ~/cobol/multiprog
cobcrun -M /home/me/cobol/multiprog multiprog

# sample in a job control scenario
# exit code 0 is ok, 1 to 9 and the catch-all are problems,
#     30 thru 89 are special case codes that start program30, ..., program89
cobcrun -M /home/me/cobol/multiprog program27 "program27-inputfilename.dat" \
"program27-outputfilename.rpt"
case $? in
            0) echo "program27 complete" ;;
        [1-9]) echo "program27 fell over with status $?" ;;
   [3-8][0-9]) cobcrun -M /home/me/cobol/multiprog program$? "for say, state taxes"
            *) echo "batch job fell over with status $?" ;;
esac

3.7   What is cob-config?

cob-config is a small program that can be used to display the C compiler flags and libraries required for compiling. Using GNU/Linux for example

$ cob-config
Usage: cob-config [OPTIONS]
Options:
        [--prefix[=DIR]]
        [--exec-prefix[=DIR]]
        [--version]
        [--libs]
        [--cflags]
$ cob-config --libs
-L/usr/local/lib -lcob -lm -lgmp -lncurses -ldb
$ cob-config --cflags
-I/usr/local/include

You may need to use these features during mixed source language development, usually by back-ticking the command output inline with other gcc commands.

3.8   What compiler options are supported?

The GnuCOBOL system strives to follow standards, yet also remain a viable compiler option for the many billions of existing lines of COBOL sources, by supporting many existing extensions to the COBOL language. Many details of the compile can be controlled with command line options. Please also see What are the GnuCOBOL compile time configuration files? for more details on this finely tuned control.

$ cobc -V
cobc (GnuCOBOL) 1.1.0
Copyright (C) 2001-2008 Keisuke Nishida / Roger While
Built    Oct 29 2008 16:32:02
Packaged Oct 28 2008 19:05:45 CET

$ cobc --help
Usage: cobc [options] file...

Options:
  --help                Display this message
  --version, -V         Display compiler version
  -v                    Display the programs invoked by the compiler
  -x                    Build an executable program
  -m                    Build a dynamically loadable module (default)
  -std=<dialect>        Compile 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                    Produce debugging information in the output
  -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, assemble or link
  -C                    Translation only; convert COBOL to C
  -S                    Compile only; output assembly file
  -c                    Compile and assemble, but do not link
  -t <file>             Generate and place a program listing into <file>
  -I <directory>        Add <directory> to copy/include search path
  -L <directory>        Add <directory> to library search path
  -l <lib>              Link the library <lib>
  -D <define>           Pass <define> to the C compiler
  -conf=<file>          User defined dialect configuration - See -std=
  --list-reserved       Display reserved words
  --list-intrinsics     Display intrinsic functions
  --list-mnemonics      Display mnemonic names
  -save-temps(=<dir>)   Save intermediate files (default current directory)
  -MT <target>          Set target file used in dependency list
  -MF <file>            Place dependency list into <file>
  -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
  -Wparentheses         Warn lack of parentheses around AND within OR
  -Wstrict-typing       Warn type mismatch strictly
  -Wimplicit-define     Warn implicitly defined data items
  -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)

  -ftrace               Generate trace code (Executed SECTION/PARAGRAPH)
  -ftraceall            Generate trace code (Executed SECTION/PARAGRAPH/STATEMENTS)
  -fsyntax-only         Syntax error checking only; don't emit any output
  -fdebugging-line      Enable debugging lines ('D' in indicator column)
  -fsource-location     Generate source location code (Turned on by -debug or -g)
  -fimplicit-init       Do automatic initialization of the Cobol runtime system
  -fsign-ascii          Numeric display sign ASCII (Default on ASCII machines)
  -fsign-ebcdic         Numeric display sign EBCDIC (Default on EBCDIC machines)
  -fstack-check         PERFORM stack checking (Turned on by -debug or -g)
  -ffold-copy-lower     Fold COPY subject to lower case (Default no transformation)
  -ffold-copy-upper     Fold COPY subject to upper case (Default no transformation)
  -fnotrunc             Do not truncate binary fields according to PICTURE
  -ffunctions-all       Allow use of intrinsic functions without FUNCTION keyword
  -fmfcomment           '*' or '/' in column 1 treated as comment (FIXED only)
  -fnull-param          Pass extra NULL terminating pointers on CALL statements

3.8.1   For 2.0 that becomes

GnuCOBOL compiler for most COBOL dialects with lots of extensions

Usage: cobc [options]... file...

Options:
  -h, -help             display this help and exit
  -V, -version          display compiler version and exit
  -i, -info             display compiler information (build/environment)
  -v, -verbose          display compiler version and the commands
                        invoked by the compiler
  -vv, -verbose=2       like -v but additional pass verbose option
                        to assembler/compiler
  -vvv, -verbose=3      like -vv but additional pass verbose option
                        to linker
  -q, -brief            reduced displays, commands invoked not shown
  -###                 like -v but commands not executed
  -x                    build an executable program
  -m                    build a dynamically loadable module (default)
  -j [<args>], -job[=<args>]    run program after build, passing <args>
  -std=<dialect>        warnings/features for a specific dialect
                        <dialect> can be one of:
                        cobol2014, cobol2002, cobol85, default,
                        ibm, mvs, bs2000, mf, acu;
                        see configuration files in directory config
  -F, -free             use free source format
  -fixed                use fixed source format (default)
  -O, -O2, -Os          enable optimization
  -g                    enable C compiler debug / stack check / trace
  -d, -debug            enable all run-time error checking
  -o <file>             place the output into <file>
  -b                    combine all input files into a single
                        dynamically loadable module
  -E                    preprocess only; do not compile or link
  -C                    translation only; convert COBOL to C
  -S                    compile only; output assembly file
  -c                    compile and assemble, but do not link
  -T <file>             generate and place a wide program listing
  into <file>
  -t <file>             generate and place a program listing into <file>
  --tlines=<lines>      specify lines per page in listing, default = 55
  --no-symbols          specify no symbols in listing
  -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> for COBOL compilation
  -K <entry>            generate CALL to <entry> as static
  -conf=<file>          user-defined dialect configuration; see -std
  -list-reserved        display reserved words
  -list-intrinsics      display intrinsic functions
  -list-mnemonics       display mnemonic names
  -list-system          display system routines
  -save-temps[=<dir>]   save intermediate files
                        - default: current directory
  -ext <extension>      add file extension for resolving COPY

  -W                    enable all warnings
  -Wall                 enable most warnings (all except as noted below)
  -Wno-<warning>        disable warning enabled by -W or -Wall
  -Wno-unfinished       don't warn if unfinished features are used
                        - ALWAYS active
  -Wobsolete            warn if obsolete features are used
  -Warchaic             warn if archaic features are used
  -Wredefinition        warn incompatible redefinition of data items
  -Wconstant            warn inconsistent constant
  -Woverlap             warn overlapping MOVE items
  -Wpossible-overlap    warn MOVE items that may overlap depending
  on variables
                        - NOT set with -Wall
  -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
  -Winitial-value       warn Initial VALUE clause ignored
  -Wprototypes          warn missing FUNCTION prototypes/definitions
  -Wcall-params         warn non 01/77 items for CALL params
                        - NOT set with -Wall
  -Wcolumn-overflow     warn text after program-text area, 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=[ASCII|EBCDIC] define display sign representation
                        - default: machine native
  -ffold-copy=[UPPER|LOWER]     fold COPY subject to value
                        - default: no transformation
  -ffold-call=[UPPER|LOWER]     fold PROGRAM-ID, CALL, CANCEL subject
  to value
                        - default: no transformation
  -fdefaultbyte=0..255  initialize fields without VALUE to decimal value
                        - default: initialize to picture
  -fintrinsics=[ALL|intrinsic function name(,name,...)] intrinsics to
  be used without FUNCTION keyword
  -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
                        - e.g. 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
  -facucomment          '$' in indicator area treated as '*',
                        '|' treated as floating comment
  -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
  -foptional-file       treat all files as OPTIONAL
                        - unless NOT OPTIONAL specified

  -ftab-width=1..12     set number of spaces that are asumed for tabs
  -ftext-column=72..255 set right margin for source (fixed format only)
  -fpic-length=<number> maximum number of characters allowed in the
  character-string
  -fword-length=1..61   maximum word-length for COBOL words / Programmer
  defined words
  -fliteral-length=<number>     maximum literal size in general
  -fnumeric-literal-length=1..38        maximum numeric literal size
  -fassign-clause=<value>       set way of interpreting ASSIGN
  -fbinary-size=<value> binary byte size - defines the allocated bytes
  according to PIC
  -fbinary-byteorder=<value>    binary byte order
  -ffilename-mapping    resolve file names at run time using environment
  variables.
  -fpretty-display      alternate formatting of numeric fields
  -fbinary-truncate     numeric truncation according to ANSI
  -fcomplex-odo         allow complex OCCURS DEPENDING ON
  -findirect-redefines  allow REDEFINES to other than last equal level
  number
  -flarger-redefines-ok allow larger REDEFINES items
  -frelax-syntax-checks allow certain syntax variations (e.g. REDEFINES
  position)
  -fperform-osvs        exit point of any currently executing perform
  is recognized if reached
  -fsticky-linkage      linkage-section items remain allocated between
  invocations
  -frelax-level-hierarchy       allow non-matching level numbers
  -fhostsign            allow hexadecimal value 'F' for NUMERIC test of
  signed PACKED DECIMAL field
  -faccept-update       set WITH UPDATE clause as default for ACCEPT
  dest-item, instead of WITH NO UPDATE
  -faccept-auto         set WITH AUTO clause as default for ACCEPT
  dest-item, instead of WITH TAB
  -fconsole-is-crt      assume CONSOLE IS CRT if not set otherwise
  -fprogram-name-redefinition   program names don't lead to a reserved
  identifier
  -fno-echo-means-secure        NO-ECHO hides input with asterisks
  like SECURE
  -fcomment-paragraphs=<support>        comment paragraphs in
  IDENTIFICATION DIVISION (AUTHOR, DATE-WRITTEN, ...)
  -fmemory-size-clause=<support>        MEMORY-SIZE clause
  -fmultiple-file-tape-clause=<support> MULTIPLE-FILE-TAPE clause
  -flabel-records-clause=<support>      LABEL-RECORDS clause
  -fvalue-of-clause=<support>   VALUE-OF clause
  -fdata-records-clause=<support>       DATA-RECORDS clause
  -ftop-level-occurs-clause=<support>   OCCURS clause on top-level
  -fsynchronized-clause=<support>       SYNCHRONIZED clause
  -fgoto-statement-without-name=<support>       GOTO statement without
  name
  -fstop-literal-statement=<support>    STOP-LITERAL statement
  -fdebugging-line=<support>    DEBUGGING MODE and indicator 'D'
  -fuse-for-debugging=<support> USE FOR DEBUGGING
  -fpadding-character-clause=<support>  PADDING CHARACTER clause
  -fnext-sentence-phrase=<support>      NEXT SENTENCE phrase
  -feject-statement=<support>   EJECT statement
  -fentry-statement=<support>   ENTRY statement
  -fmove-noninteger-to-alphanumeric=<support>   move noninteger to
  alphanumeric
  -fodo-without-to=<support>    OCCURS DEPENDING ON without to
  -fsection-segments=<support>  section segments
  -falter-statement=<support>   ALTER statement
  -fcall-overflow=<support>     OVERFLOW clause for CALL
  -fnumeric-boolean=<support>   boolean literals (B'1010')
  -fhexadecimal-boolean=<support>       hexadecimal-boolean literals
  (BX'A')
  -fnational-literals=<support> national literals (N'UTF-16 string')
  -fhexadecimal-national-literals=<support>     hexadecimal-national
  literals (NX'265E')
  -facucobol-literals=<support> ACUCOBOL-GT literals (#B #O #H #X)
  -fword-continuation=<support> continuation of COBOL words
  -fnot-exception-before-exception=<support>    NOT ON EXCEPTION before
  ON EXCEPTION
  -faccept-display-extensions=<support> extensions to ACCEPT and DISPLAY
  -frenames-uncommon-levels=<support>   RENAMES of 01-, 66- and 77-level
  items
  -fprogram-prototypes=<support>        CALL/CANCEL with
  program-prototype-name
  -freference-out-of-declaratives=<support>     references to sections
  not in DECLARATIVES from within DECLARATIVES
        where <support> is one of the following:
        'ok', 'warning', 'archaic', 'obsolete', 'skip', 'ignore', 'error',
        'unconformable'
  -fnot-reserved=<word> word to be taken out of the reserved words list
  -freserved=<word>     word to be added to reserved words list
  -freserved=<word>:<alias>     word to be added to reserved words list
  as alias


Report bugs to: bug-gnucobol@gnu.org
or (preferably) use the issue tracker via the home page.
GnuCOBOL home page: <http://www.gnu.org/software/gnucobol/>
General help using GNU software: <http://www.gnu.org/gethelp/>

3.8.2   For reportwriter that becomes

prompt$ cobc --info
cobc (GnuCOBOL) 2.0.0
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Keisuke Nishida, Roger While, Ron Norman, Simon Sobisch, Edward
Hart
Built     Jun 15 2016 07:38:33
Packaged  Oct 25 2015 21:40:28 UTC
C version "5.2.1 20151010"

build information
build environment        : x86_64-pc-linux-gnu
CC                       : gcc
CPPFLAGS                 :
CFLAGS                   : -g -O0 -pipe -fsigned-char -Wall
                           -Wwrite-strings -Wmissing-prototypes
                           -Wno-format-y2k
LD                       : /usr/bin/ld -m elf_x86_64
LDFLAGS                  : -Wl,-z,relro,-z,now,-O1

GnuCOBOL information
COB_CC                   : gcc
COB_CFLAGS               : -I/usr/local/include -pipe
COB_LDFLAGS              :
  env: COB_LDFLAGS       : -Wl,--no-as-needed
COB_LIBS                 : -L/usr/local/lib -lcob -lm -lvbisam -lgmp
                           -lncurses -ldl
COB_CONFIG_DIR           : /usr/local/share/gnu-cobol/config
COB_COPY_DIR             : /usr/local/share/gnu-cobol/copy
COB_MSG_FORMAT           : GCC
COB_MODULE_EXT           : so
COB_EXEEXT               :
64bit-mode               : yes
BINARY-C-LONG            : 8 bytes
Extended screen I/O      : ncurses
Variable format          : 0
Sequential handler       : Internal
ISAM handler             : VBISAM

prompt$ cobc --help
GnuCOBOL compiler for most COBOL dialects with lots of extensions

usage: cobc [options]... file...

options:
  -h, -help             display this help and exit
  -V, -version          display compiler version and exit
  -i, -info             display compiler information (build/environment)
  -v, -verbose          display the commands invoked by the compiler
  -vv                   display compiler version and the commands
                        invoked by the compiler
  -x                    build an executable program
  -m                    build a dynamically loadable module (default)
  -j(=<args>), -job(=<args>) run job, with optional arguments passed to program/module
  -std=<dialect>        warnings/features for a specific dialect
                        <dialect> can be one of:
                        cobol2014, cobol2002, cobol85, default,
                        ibm, mvs, bs2000, mf, acu;
                        see configuration files in directory config
  -F, -free             use free source format
  -fixed                use fixed source format (default)
  -O, -O2, -Os          enable optimization
  -g                    enable C compiler debug / stack check / trace
  -d, -debug            enable all run-time error checking
  -o <file>             place the output into <file>
  -b                    combine all input files into a single
                        dynamically loadable module
  -E                    preprocess only; do not compile or link
  -C                    translation only; convert COBOL to C
  -S                    compile only; output assembly file
  -c                    compile and assemble, but do not link
  -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> for COBOL compilation
  -K <entry>            generate CALL to <entry> as static
  -conf=<file>          user defined dialect configuration - See -std=
  -cb_conf=<tag:value>  override configuration entry
  -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
  -Wno-<feature>        disable warning enabled by -W or -Wall
  -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
  -Wprototypes          warn missing FUNCTION prototypes/definitions
  -Wcall-params         warn non 01/77 items for CALL params
                        - NOT set with -Wall
  -Wcolumn-overflow     warn text after program-text area, 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
  -facucomment          '$' in indicator area treated as '*',
                        '|' treated as floating comment
  -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


Report bugs to: bug-gnucobol@gnu.org or
use the preferred issue tracker via home page.
GnuCOBOL home page: <http://www.gnu.org/software/gnucobol/>
General help using GNU software: <http://www.gnu.org/gethelp/>

3.8.3   A note on -A and -Q

The -A and -Q swiches can get a bit tricky. These pass options on to the C compiler and some escaping is sometimes necessary.

For example: To pass a defined symbol all the way through to the Assembly layer you could use:

cobc -xjgv -debug -A '-Wa\,--defsym,DEBUG=1' cpuid.cob vendor.s brand.s negate.s

to inform the compiler toolchain to pass the option to gcc, which would then pass the option to as, as in:

Command line:   cobc -xjgv -debug -A -Wa\,--defsym,DEBUG=1 cpuid.cob vendor.s brand.s negate.s
Preprocessing:  cpuid.cob -> cpuid.i
Return status:  0
Parsing:        cpuid.i (cpuid.cob)
Return status:  0
Translating:    cpuid.i -> cpuid.c (cpuid.cob)
Executing:      gcc -std=gnu99 -c -I/usr/local/include -pipe -Wno-unused
                -fsigned-char -Wno-pointer-sign -g -Wa\,--defsym,DEBUG=1 -o
                "/tmp/cob8643_0.o" "cpuid.c"
Return status:  0
Executing:      gcc -std=gnu99 -c -I/usr/local/include -pipe -Wno-unused
                -fsigned-char -Wno-pointer-sign -g -Wa\,--defsym,DEBUG=1 -fPIC
                -DPIC -o "/tmp/cob8643_1.o" "vendor.s"
Return status:  0
Executing:      gcc -std=gnu99 -c -I/usr/local/include -pipe -Wno-unused
                -fsigned-char -Wno-pointer-sign -g -Wa\,--defsym,DEBUG=1 -fPIC
                -DPIC -o "brand.o" "brand.s"
Return status:  0
Executing:      gcc -std=gnu99 -c -I/usr/local/include -pipe -Wno-unused
                -fsigned-char -Wno-pointer-sign -g -Wa\,--defsym,DEBUG=1 -fPIC
                -DPIC -o "negate.o" "negate.s"
Return status:  0
Executing:      gcc -std=gnu99 -Wl,--export-dynamic -o "cpuid"
                "/tmp/cob8643_0.o" "/tmp/cob8643_1.o" "brand.o" "negate.o"
                -L/usr/local/lib -lcob -lm -lvbisam -lgmp -lncursesw -ldl
Return status:  0

Executing:      ./cpuid
Vendor: AuthenticAMD, with highest CPUID function: 13
CPUID normal maximum  : 00000000000000000013
Processor Brand string: AMD A10-5700 APU with Radeon(tm) HD Graphics
Number: 7fffffe2, Address: 0x6031e0
Number: 8000001e, Address: 0x6031e0
CPUID extended maximum: 00000000002147483678, 0x8000001E
Return status:  0

In this case the assembler support files included these lines

.ifdef DEBUG
# prep the printf call, args are rdi, rsi, rdx and rax
    movq    $msg, %rdi
    movl    %edx, %esi
    movq    8(%rsp), %rdx
    xorb    %al,%al
    call    printf
.endif

with conditional assembly directives that produced the:

Number: 7fffffe2, Address: 0x6031e0
Number: 8000001e, Address: 0x6031e0

output lines during the execution of cpuid, by assembling in calls to printf. In this case ALL the assembled files are getting the DEBUG=1 definition, and finer control would mean splitting up the cobc command into separate steps, if that was not wanted in some of the other assembler files.

3.9   What dialects are supported by GnuCOBOL?

Using the std= compiler option, GnuCOBOL can be configured to compile using specific historical COBOL compiler features and quirks.

Supported dialects include:

  • default
  • acu
  • cobol85
  • cobol2002
  • cobol2014
  • ibm
  • mvs
  • mf
  • bs2000

For details on what options and switches are used to support these dialect compiles, see the config/ directory of your GnuCOBOL installation. For Debian GNU/Linux, that will be /usr/share/open-cobol/config/ if you used APT to install a GnuCOBOL package or /usr/local/share/open-cobol/config/ after a build from the source archive. Or, /usr/share/gnucobol/config for packages from the GnuCOBOL versions of the source tree, as they become available.

For example: the bs2000.conf file restricts data representations to 2, 4 or 8 byte binary while mf.conf allows data representations from 1 thru 8 bytes. cobol85.conf allows debugging lines, cobol2002.conf configures the compiler to warn that this feature is obsolete.

3.9.1   Supported Literal values

GnuCOBOL strives to be a useful COBOL compiler. By supporting features provided by other compilers, there are some extensions in GnuCOBOL that will not be in the COBOL standards document. GnuCOBOL does not claim any level of conformance with any official COBOL specifications, but does strive to be useful.

The cobc compiler supports:

DISPLAY B#101
DISPLAY O#1777777777777777777777
DISPLAY X#ffffffffffffffff
DISPLAY H#ffffffffffffffff

DISPLAY "ABC" & "DEF"  *> literal concatenation
DISPLAY X"0a00"
DISPLAY H"DECAFBAD"
   MOVE Z"C-string" TO nine-character-field-with-zero-byte

3.10   What extensions are used if cobc is called with/without “-ext” for COPY?

From Roger on opencobol.org

In the following order -
CPY, CBL, COB, cpy, cbl, cob and finally with no extension.

User specified extensions (in the order as per command line) are inspected
PRIOR to the above defaults.

ie. They take precedence.

From Simon on SourceForge

The standard extensions for copybooks are (in the given order):

    no extension
    CPY
    CBL
    COB
    cpy
    cbl
    cob

Given

    COBCPY=/globdir1:../globdir2

and a command line with

    "-I/mydir1 -I ../mydir2 -e myext"

and the standard installation path for COB_COPY_DIR

    /usr/local/share/gnu-cobol/config

with the statement "COPY mybook." The following files are checked, in the
following order (relative to current file)

    mybook
    mybook.myext
    mybook.CPY
    mybook.CBL
    mybook.COB
    mybook with lowercase standard extensions (cpy, cbl, cob)
    /mydir1/mybook
    /mydir1/mybook.myext
    /mydir1/mybook.CPY
    /mydir1/mybook.CBL
    /mydir1/mybook with other standard extensions
    ../mydir2/mybook
    ../mydir2/mybook.myext
    ../mydir2/mybook.CPY
    ../mydir2/mybook.CBL
    ../mydir2/mybook with other standard extensions
    /globdir1/mybook
    /globdir1/mybook.myext
    /globdir1/mybook.CPY
    /globdir1/mybook.CBL
    /globdir1/mybook with other standard extensions
    ../globdir2/mybook
    ../globdir2/mybook.myext
    ../globdir2/mybook.CPY
    ../globdir2/mybook.CBL
    ../globdir2/mybook with other standard extensions
    /usr/local/share/gnu-cobol/copy/mybook
    /usr/local/share/gnu-cobol/copy/mybook.myext
    /usr/local/share/gnu-cobol/copy/mybook.CPY
    /usr/local/share/gnu-cobol/copy/mybook.CBL
    /usr/local/share/gnu-cobol/copy/mybook with other standard extensions

If all these 64 files are not found you'll see

    myprog.cob:line: Error: mybook: file not found

The /usr/local/share/gnu-cobol is relative to the installation prefix. It might be /usr/share/gnu-cobol or other system directory, and can be set during ./configure when building GnuCOBOL from source.

3.11   What are the GnuCOBOL compile time configuration files?

To assist in the support of the various existent COBOL compilers, GnuCOBOL reads configuration files controlling various aspects of a compile pass.

Each supported dialect will also have a .conf file in the config/ sub-directory of its installation. For Debian GNU/Linux, these will be in /usr/share/open-cobol/config/ or /usr/local/share/open-cobol/config under default package and default make conditions.

For example, the default configuration, default.conf is:

# COBOL compiler configuration                                        -*- sh -*-

# Value: any string
name: "GnuCOBOL"

# Value: int
tab-width: 8
text-column: 72

# Value: `cobol2002', `mf', `ibm'
#
assign-clause: mf

# If yes, file names are resolved at run time using environment variables.
# For example, given ASSIGN TO "DATAFILE", the actual 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.
#
# Value: `yes', `no'
filename-mapping: yes

# Value: `yes', `no'
pretty-display: yes

# Value: `yes', `no'
auto-initialize: yes

# Value: `yes', `no'
complex-odo: no

# Value: `yes', `no'
indirect-redefines: no

# Value:         signed  unsigned  bytes
#                ------  --------  -----
# `2-4-8'        1 -  4                2
#                5 -  9                4
#               10 - 18                8
#
# `1-2-4-8'      1 -  2                1
#                3 -  4                2
#                5 -  9                4
#               10 - 18                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

# Value: `yes', `no'
binary-truncate: yes

# Value: `native', `big-endian'
binary-byteorder: big-endian

# Value: `yes', `no'
larger-redefines-ok: no

# Value: `yes', `no'
relaxed-syntax-check: no

# Perform type OSVS - If yes, the exit point of any currently executing perform
# is recognized if reached.
# Value: `yes', `no'
perform-osvs: no

# If yes, non-parameter linkage-section items remain allocated
# between invocations.
# Value: `yes', `no'
sticky-linkage: no

# If yes, allow non-matching level numbers
# Value: `yes', `no'
relax-level-hierarchy: no

# not-reserved:
# Value: Word to be taken out of the reserved words list
# (case independent)

# Dialect features
# Value: `ok', `archaic', `obsolete', `skip', `ignore', `unconformable'
author-paragraph:                        obsolete
memory-size-clause:                        obsolete
multiple-file-tape-clause:                obsolete
label-records-clause:                obsolete
value-of-clause:                        obsolete
data-records-clause:                obsolete
top-level-occurs-clause:                skip
synchronized-clause:                ok
goto-statement-without-name:        obsolete
stop-literal-statement:                obsolete
debugging-line:                        obsolete
padding-character-clause:                obsolete
next-sentence-phrase:                archaic
eject-statement:                        skip
entry-statement:                        obsolete
move-noninteger-to-alphanumeric:    error
odo-without-to:                        ok

3.11.1   reportwriter default.conf

# GnuCOBOL compiler configuration
#
# Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Keisuke Nishida
# Copyright (C) 2007-2012 Roger While
#
# This file is part of GnuCOBOL.
#
# The GnuCOBOL compiler is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# GnuCOBOL is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GnuCOBOL.  If not, see <http://www.gnu.org/licenses/>.


# Value: any string
name: "GnuCOBOL"

# 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

3.11.2   differences with ibm.conf

$ diff -u config/default.conf config/ibm.conf
--- config/default.conf 2014-02-21 14:29:56.154806798 -0500
+++ config/ibm.conf     2014-02-21 14:29:56.159806822 -0500
@@ -20,10 +20,10 @@


 # Value: any string
-name: "GnuCOBOL"
+name: "IBM COBOL"

 # Value: enum
-standard-define                        0
+standard-define                        2
 #        CB_STD_OC = 0,
 #        CB_STD_MF,
 #        CB_STD_IBM,
@@ -38,7 +38,7 @@

 # Value: 'mf', 'ibm'
 #
-assign-clause:                 mf
+assign-clause:                 ibm

 # If yes, file names are resolved at run time using
 # environment variables.
@@ -52,13 +52,13 @@
 filename-mapping:              yes

 # Alternate formatting of numeric fields
-pretty-display:                        yes
+pretty-display:                        no

 # Allow complex OCCURS DEPENDING ON
-complex-odo:                   no
+complex-odo:                   yes

 # Allow REDEFINES to other than last equal level number
-indirect-redefines:            no
+indirect-redefines:            yes

 # Binary byte size - defines the allocated bytes according to PIC
 # Value:         signed  unsigned  bytes
@@ -81,10 +81,10 @@
 #               15 - 16   15 - 16      7
 #               17 - 18   17 - 18      8
 #
-binary-size:                   1-2-4-8
+binary-size:                   2-4-8

 # Numeric truncation according to ANSI
-binary-truncate:               yes
+binary-truncate:               no

 # Binary byte order
 # Value: 'native', 'big-endian'
@@ -98,20 +98,20 @@

 # Perform type OSVS - If yes, the exit point of any currently
 # executing perform is recognized if reached.
-perform-osvs:                  no
+perform-osvs:                  yes

 # If yes, linkage-section items remain allocated
 # between invocations.
-sticky-linkage:                        no
+sticky-linkage:                        yes

 # If yes, allow non-matching level numbers
-relax-level-hierarchy:         no
+relax-level-hierarchy:         yes

 # 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
+hostsign:                      yes

 # not-reserved:
 # Value: Word to be taken out of the reserved words list
@@ -125,8 +125,8 @@
 author-paragraph:                      obsolete
 data-records-clause:                   obsolete
 debugging-line:                                obsolete
-eject-statement:                       skip
-entry-statement:                       obsolete
+eject-statement:                       ok
+entry-statement:                       ok
 goto-statement-without-name:           obsolete
 label-records-clause:                  obsolete
 memory-size-clause:                    obsolete
@@ -138,5 +138,5 @@
 section-segments:                      ignore
 stop-literal-statement:                        obsolete
 synchronized-clause:                   ok
-top-level-occurs-clause:               ok
+top-level-occurs-clause:               skip
 value-of-clause:                       obsolete

3.12   Does GnuCOBOL work with make?

Absolutely. Very well, but no built in rules for GNU make yet.

Makefile command entries, (after the rule, commands are normally preceded by TAB, not spaces, but for the sake of this FAQ, a different RECIPEPREFIX is used to allow easier copy’n’paste from the web browser).

A sample (unsophisticated) makefile

# Makefile for the GnuCOBOL FAQ
# Brian Tiffin, Modified: 2015-11-14/06:58-0500
# Dedicated to the public domain, all rights waived
.RECIPEPREFIX = >

# default options, note that -g will leave intermediate files
COBCOPTS = -W -g -debug

# filenames to cleanup
COBCCLEAN = $*.c $*.s $*.i $*.c.h $*.c.l* $*.so $*.html $*

# Simple GnuCOBOL rules.  Customize to taste,
# create an executable
%: %.cob
> cobc $(COBCOPTS) -x $^ -o $@

# create an executable, and run it
%.run: %.cob
> cobc $(COBCOPTS) -xj $^ -o $@

# create an executable, and mark date-compiled
#%.mark: %.cob
#> sed -i 's#date-compiled\..*$$#date-compiled\. '\
#"$$(date +%Y-%m-%d/%H:%M%z)"'\.#' $^
#> cobc $(COBCOPTS) -x $^ -o $@

# create a dynamic module
%.so: %.cob
> cobc $(COBCOPTS) -m $^ -o $@

# create a linkable object
%.o: %.cob
> cobc $(COBCOPTS) -c $^ -o $@

# generate C code
%.c: %.cob
> cobc $(COBCOPTS) -C $^

# generate assembly
%.s: %.cob
> cobc $(COBCOPTS) -S $^

# generate intermediates in tmps
%.i: %.cob
> [ -d tmps ] || mkdir tmps
> cobc $(COBCOPTS) --save-temps=tmps -c $^

# create an executable; if errors, call vim in quickfix
%.q: %.cob
> cobc $(COBCOPTS) -x $^ 2>errors.err || vi -q

# make binary; capture warnings, call vim quickfix
%.qw: %.cob
> cobc $(COBCOPTS) -x $^ 2>errors.err ; vi -q

# run ocdoc to get documentation
%.ocdoc: %.cob
> ./ocdoc $^ $*.rst $*.html $*.css

# run rst2html
%.html: %.cob
> sed ':loop;/!rst.marker!/{d};N;b loop' $^ | sed '$$d' \
    | sed 's/:SAMPLE:/$*/' | rst2html >$*.html

# run cobxref
%.lst: %.cob
> cobc $(COBCOPTS) -Xref $^

# run cobolmac, .cbl to .cob
%.mac: %.cbl
> cobolmac <$^ >$*.cob

# clean up -g files, with interactive prompting, just in case
%.clean: %.cob
> @echo "Remove: " $(COBCCLEAN)
> @(read -p "Are you sure? " -r; \
    if [[ $$REPLY =~ ^[Yy]$$ ]]; then rm $(COBCCLEAN) ; fi)

# tectonics for occurlrefresh
occurlrefresh: occurl.c occurlsym.cpy occurlrefresh.cbl
> cobc -x $(COBCOPTS) occurlrefresh.cbl occurl.c -lcurl

And now to work with a small program called program.cob, use

prompt$ make program       # for executables
prompt$ make program.run   # compile and run
prompt$ make program.mark  # change date-compiled and compile
prompt$ make program.o     # for object files
prompt$ make program.so    # for shared library
prompt$ make program.q     # compile and call vi in quickfix mode
prompt$ make program.clean # clean up cobc generated files
prompt$ make program.html  # generate documentation

The last rule, occurlrefresh is an example of how a multi-part project can be supported. Simply type

$ make occurlrefresh

and make will check the timestamps for occurl.c, occurlsym.cpy and occurlrefresh.cbl and then build up the executable if any of those files have changed compared to the timestamp of the binary.

The program.mark rule is a little dangerous, it modifies the source before continuing on to cobc -x. Probably not overly wise in a production environment.

See Tectonics for another word to describe building code.

3.13   Do you have a reasonable source code skeleton for GnuCOBOL?

Maybe. Style is a very personal developer choice. GnuCOBOL pays homage to this freedom of choice.

Below is a template that can be loaded into Vim when editing new files of type .cob or .cbl.

" Auto load COBOL template
autocmd BufNewFile  *.cob      0r ~/lang/cobol/header.cob
autocmd BufNewFile  *.cbl      0r ~/lang/cobol/header.cob

The filename is installation specific, and would need to change in any given ~/.vimrc config file. But in the local case, it loads from $HOME/lang/cobol/header.cob and looks like:

GCobol >>SOURCE FORMAT IS FREE
REPLACE ==:SAMPLE:== BY ==program-name==.
>>IF docpass NOT DEFINED
      *> ***************************************************************
      *>****J* project/:SAMPLE:
      *> AUTHOR
      *>   Brian Tiffin
      *> DATE
      *>   20150405  Modified:
      *> LICENSE
      *>   Copyright 2015 Brian Tiffin
      *>   GNU Lesser General Public License, LGPL, 3.0 (or greater)
      *> PURPOSE
      *>   :SAMPLE: program.
      *> TECTONICS
      *>   cobc -x -g -debug :SAMPLE:.cob
      *> ***************************************************************
       identification division.
       program-id. :SAMPLE:.
       author.
       date-compiled.
       date-written.
       installation.
       remarks.
       security.

       environment division.
       configuration section.
       source-computer.
       object-computer.
       special-names.
       repository.
           function all intrinsic.

       input-output section.
       file-control.
       i-o-control.

       data division.
       file section.

       working-storage section.

       local-storage section.
       linkage section.
       report section.
       screen section.

      *> ***************************************************************
       procedure division.

       goback.
      *> ***************************************************************

      *> informational warnings and abends
       soft-exception.
         display "Module:              " module-id upon syserr
         display "Module-path:         " module-path upon syserr
         display "Module-source:       " module-source upon syserr
         display "Exception-file:      " exception-file upon syserr
         display "Exception-status:    " exception-status upon syserr
         display "Exception-location:  " exception-location upon syserr
         display "Exception-statement: " exception-statement upon syserr
       .

       hard-exception.
           perform soft-exception
           stop run returning 127
       .

       end program :SAMPLE:.
      *> ***************************************************************
      *>****
>>ELSE
!rst-marker!
========
:SAMPLE:
========

.. contents::

Introduction
------------

Usage
-----

    prompt$ ./:SAMPLE:

Source
------

.. include::  :SAMPLE:.cob
   :code: cobolfree
   :end-before: !rst-marker
>>END-IF

It includes empty versions (that still compile) of most sections, in the right order. Deleting the unnecessary lines is pretty easy, and act as handy reminders.

This skeleton also includes starter lines for in source documentation. The only rule for those documentation lines is that no line can start with > or $ (as that would trigger the GnuCOBOL preprocessor as it scans through the text looking for >>END-IF, or >>ELSE, or other compiler directives). These lines can be processed with rst2html and there is a sample make rule listed under, Does GnuCOBOL work with make? as make program.html that includes the simple steps for extracting and processing the documentation.

A few other ./vimrc settings allow for automatically filling in the author and date-written paragraphs, as well as setting the Modified: timestamp when writing out the buffer. Customize with your own name and timestamp preferences.

" Auto update modified time stamp
"    Modified: must occur in the first 32 lines,
"    32 chars of data before Modified: tag remembered
"    modify strftime to suit
function! LastModified()
    if &modified
        let save_cursor = getpos(".")
        let n = min([32, line("$")])
        keepjumps exe '1,' . n . 's#^\(.\{,32}Modified:\).*#\1'
            \ . strftime(" %Y-%m-%d/%H:%M%z") . '#e'
        keepjumps exe '1,' . n . 's#^\(.\{,32}@modified \).*#\1'
            \ . strftime("%Y-%m-%d/%H:%M%z") . '#e'
        keepjumps exe '1,' . n . 's#^\(.\{,32}author.\)$#\1'
            \ . ' YOUR NAME HERE.' . '#e'
        keepjumps exe '1,' . n . 's#^\(.\{,32}date-written.\).*#\1'
            \ . strftime(" %Y-%m-%d/%H:%M%z") . '.' . '#e'
        call histdel('search', -1)
        call setpos('.', save_cursor)
    endif
endfunction
au BufWritePre * call LastModified()

Here is a FIXED form header that this author used to use. It includes ocdoc lines.

GCobol >>SOURCE FORMAT IS FIXED
      *> ***************************************************************
      *><* ===========
      *><*
      *><* ===========
      *><* :Author:
      *><* :Date:
      *><* :Purpose:
      *><* :Tectonics: cobc
      *> ***************************************************************
       identification division.
       program-id. .

       environment division.
       configuration section.
       source-computer. posix.
       object-computer.

       special-names.

       repository.
           function all intrinsic.

       input-output section.
       file-control.
      *>   select
      *>   assign to
      *>   organization is
      *>   .

       data division.
       file section.
      *>fd .
      *>    01 .

       working-storage section.
       local-storage section.
       linkage section.
       screen section.

      *> ***************************************************************
       procedure division.

       goback.
       end program .
      *><*
      *><* Last Update: dd-Mmm-yyyy

Fill in the program-id and end program to compile. Fill in the ocdoc title for generating documentation. See What is ocdoc? for more information on (one method of) inline documentation.

Here are some other templates that can be cut and pasted.

Fixed form, in lowercase, with some starter lines thrown in as reminders.

GNU    >>SOURCE FORMAT IS FIXED
Cobol *> ***************************************************************
      *> Author:
      *> Date:
      *> Purpose:
      *> Tectonics: cobc -x -g head-full.cob
      *>            COB_SET_DEBUG=Y ./head-full
      *> ***************************************************************
  id   identification division.
       program-id. sample.

 site  environment division.
       configuration section.
       source-computer. posix with debugging mode.
       object-computer. posix.

       special-names.

       repository.
           function all intrinsic.

       input-output section.
       file-control.
           select standard-in
           assign to keyboard
           organization is line sequential
           status is stdin-file-status
           .

           select standard-out
           assign to display
           organization is line sequential
           status is stdout-file-status
           .

 data  data division.
 file  file section.
       fd standard-in.
           01 stdin-line       pic x(32768).
       fd standard-out.
           01 stdout-line      pic x(32768).

store  working-storage section.
       01 stdin-file-status.
          05 stdin-status      pic 99.
          05 stdin-substatus   pic 99.

       01 stdout-file-status.
          05 stdout-status     pic 99.
          05 stdout-substatus  pic 99.

       01 countdown            pic 99.
       01 display-count        pic z9.
       01 joke-limiter         pic x     value low-value.
          88 refrain                     value high-value.

       local-storage section.
       linkage section.
       report section.
       screen section.

      *> ***************************************************************
 code  procedure division.
 decl  declaratives.

       helpful-debug section.
           use for debugging on cleanse.
       cleanse-debug.
           display
               "DEBUG: cleansing input: " trim(stdin-line trailing)
               upon syserr
       .

       bark-on-stdin-errors section.
           use after standard error on standard-in.
       bark-stdin.
           display
               "Something bad happened on KEYBOARD" upon syserr
       .

       bark-on-stdout-errors section.
           use after standard error on standard-out.
       bark-stdout.
           display
               "Something bad happened on DISPLAY" upon syserr
       .

       end declaratives.

 main  mainline section.

      *> Turn on statement tracer lines <*
       ready trace

       open input standard-in
       if stdin-status greater than 10
           perform soft-exception
       end-if

       open output standard-out
       if stdout-status greater than 10
           perform soft-exception
       end-if

      *> Turn off statement tracer lines <*
       reset trace

       perform until stdin-status greater than 9
           move "What is your command? " to stdout-line
           write stdout-line end-write
           if stdout-status greater than 10
               perform soft-exception
           end-if

           read standard-in
               at end
                   exit perform
           end-read
           if stdin-status greater than 10
               perform soft-exception
           end-if

           perform cleanse

           evaluate stdin-line also true
               when "help"         also any
                   display "We all want a little help"
                   display "help, quit or exit exit"
               when "quit"         also any
                   display
                       "I know you want to quit, but I'm being"
                       " unfriendly; type 'exit', you user you"
               when "exit"         also refrain
                   display "fine, leaving now"
                   exit perform
               when "exit"         also any
                   display "Ha!  No quit for you"
                   display
                       "Wasting your time for "
                   end-display
                   perform varying countdown from 10 by -1
                       until countdown equal zero
                       move countdown to display-count
                       display
                           display-count "... " with no advancing
                       call
                           "fflush" using NULL
                           on exception continue
                       end-call
                       call "C$SLEEP" using 1 end-call
                   end-perform
                   display "keep trying"
                   set refrain to true
               when other
                   display "try 'help'"
           end-evaluate
       end-perform

 done  goback.

      *> ***************************************************************
 aide  helper section.

      *> rudimentary changes to stdin, show off a few functions <*
       cleanse.
           move trim(substitute(lower-case(stdin-line),
               "'", space, '"', space))
             to stdin-line
       .

 warn  soft-exception.
         display "Exception-file:      " exception-file upon syserr
         display "Exception-status:    " exception-status upon syserr
         display "Exception-location:  " exception-location upon syserr
         display "Exception-statement: " exception-statement upon syserr
       .

 fail  hard-exception.
         perform soft-exception
         stop run returning 127
       .

 unit  end program sample.

Fixed form in UPPERCASE

GCobol >>SOURCE FORMAT IS FIXED
      ******************************************************************
      * Author:
      * Date:
      * Purpose:
      * Tectonics: cobc
      ******************************************************************
       IDENTIFICATION DIVISION.
       PROGRAM-ID. .

       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.

       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT
           ASSIGN TO
           ORGANIZATION IS
           .

       DATA DIVISION.
       FILE SECTION.
       FD .
           01 .

       WORKING-STORAGE SECTION.

       LOCAL-STORAGE SECTION.

       LINKAGE SECTION.

       SCREEN SECTION.

      ******************************************************************
       PROCEDURE DIVISION.

       GOBACK.
       END PROGRAM .

The GCobol “sequence number” can safely be removed. It is there to ensure proper alignment in the browser, solely for the ReStructuredText markup used for the GnuCOBOL FAQ documentation.

FREE FORM can be compiled with cobc -free or use the supported compiler directive:

>>SOURCE FORMAT IS FREE

The above line must start in column 7 unless cobc -free is used.

*> **  >>SOURCE FORMAT IS FREE
*> *********************************************************************
*> Author:
*> Date:
*> Purpose:
*> Tectonics: cobc -free
*> *********************************************************************
identification division.
program-id. .

environment division.
configuration section.

input-output section.
file-control.
    select
        assign to
        organization is
    .

data division.
file section.
fd .
    01 .

working-storage section.

local-storage section.

linkage section.

screen section.

procedure division.

goback.
end program .

These files can be downloaded from

As listed above, head-full.cob has a lot of gunk in it, and is more useful as a reminder than a day to day default. See autoload a skeleton.

Please excuse the small sample command interpreter, it’s my homage to Python and:

$ python
Python 2.7.5 (default, Nov 12 2013, 16:18:42)
[GCC 4.8.2 20131017 (Red Hat 4.8.2-1)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit
>>>

If you know I want to exit, just exit, don’t tell me I did it wrong. Having said that, this reminder source plays out ala:

$ cobc -x -g head-full.cob
$ COB_SET_DEBUG=Y ./head-full
Source :    'head-full.cob'
Program-Id: sample           Statement: OPEN                   Line: 93
Program-Id: sample           Statement: IF                     Line: 94
Program-Id: sample           Statement: OPEN                   Line: 98
Program-Id: sample           Statement: IF                     Line: 99
Program-Id: sample           Statement: RESET TRACE            Line: 103
What is your command?

quit

DEBUG: cleansing input: quit
I know you want to quit, but I'm being unfriendly; type 'exit', you user you
What is your command?

‘exit’

DEBUG: cleansing input: 'exit'
Ha!  No quit for you
Wasting your time for
10...  9...  8...  7...  6...  5...  4...  3...  2...  1... keep trying
What is your command?

“EXIT”

DEBUG: cleansing input: "EXIT"
fine, leaving now

Note

There are tricks to ensure that FIXED FORMAT source code can be compiled in a both a FIXED and FREE FORMAT mode. That includes:

  • using free form end of line comments, *> in column 7 and 8, or later
  • no sequence numbers or notes in column 1-6, the saddest concession
  • write DEBUG line compiler directives with the >>D starting in column 5 (so the D ends up in column 7)
  • avoid - continuation lines, & being a handy replacement that may well enhance readability when literals are involved
  • judicious use of the >>SOURCE FORMAT IS ... directive, placed at column 8 or later, to toggle around tricky bits of comment and code sections

3.14   Can GnuCOBOL be used to write command line stdin, stdout filters?

Absolutely. It comes down to SELECT name ASSIGN TO KEYBOARD for standard input, and SELECT name ASSIGN TO DISPLAY for standard out.

Below is a skeleton that can be used to write various filters. These programs can be used as command line pipes, or with redirections.

$ cat datafile | filter
$ filter <inputfile >outputfile

filter.cob. You’ll want to change the 01-transform paragraph to do all the processing of each record. This skeleton simply copies stdin to stdout, with a limit of 32K records so that may need to be changed as well or tests made to ensure the default LINE SEQUENTIAL mode of KEYBOARD and DISPLAY are appropriate for the task at hand.

GCobol >>SOURCE FORMAT IS FIXED
      *> ***************************************************************
      *><* ===========
      *><* filter
      *><* ===========
      *><* :Author:    Brian Tiffin
      *><* :Date:      20090207
      *><* :Purpose:   Standard IO filters
      *><* :Tectonics: cobc -x filter.cob
      *> ***************************************************************
       identification division.
       program-id. filter.

       environment division.
       configuration section.

       input-output section.
       file-control.
           select standard-input assign to keyboard.
           select standard-output assign to display.

       data division.
       file section.
       fd standard-input.
           01 stdin-record     pic x(32768).
       fd standard-output.
           01 stdout-record    pic x(32768).

       working-storage section.
       01  file-status         pic x  value space.
           88 end-of-file             value high-value
              when set to false is          low-value.

      *> ***************************************************************
       procedure division.
       main section.
       00-main.

       perform 01-open

       perform 01-read

       perform
            until end-of-file
                perform 01-transform
                perform 01-write
                perform 01-read
       end-perform
       .

       00-leave.
       perform 01-close
       .

       goback.
      *> end main

       support section.
       01-open.
       open input standard-input
       open output standard-output
       .

       01-read.
       read standard-input
            at end set end-of-file to true
       end-read
       .

      *> All changes here
       01-transform.
       move stdin-record to stdout-record
       .
      *>

       01-write.
       write stdout-record end-write
       .

       01-close.
           close standard-input
           close standard-output
       .

       end program filter.
      *><*
      *><* Last Update: dd-Mmm-yyyy

3.14.1   CBL_GC_HOSTED

A recent entry in the GnuCOBOL system call library allows for quick access to some of the common variables hosted by the C run-time system.

CBL_GC_HOSTED provides access to

  • stdin sets pointer to stream
  • stdout sets pointer to stream
  • stderr sets pointer to stream
  • argc sets binary-long
  • argv sets pointer to char pointer pointer
  • errno sets pointer with address of errno

If GnuCOBOL is built with HAVE_TIMEZONE defined, CBL_GC_HOSTED can also return

  • tzname sets pointer to pointer to two element char pointer array
  • timezone sets binary-c-long, number of seconds West of UTC.
  • daylight sets binary-long, 0/1 flag for daylight savings time

Treat all returned values as read only, except for errno which is a reference to the actual field and can be read and modified through a BASED integer.

*> POSIX stream IO mix and match with GnuCOBOL
 01 result   usage binary-long.

 01 stdin    usage pointer.
 01 errno    usage pointer.
 01 err      usage binary-long based.

 01 buffer   pic x(80).
 01 got      usage pointer.

*> POSIX timezone information
 01 tzname   usage pointer.
 01 tznames  usage pointer based.
    05 tzs   usage pointer occurs 2 times.
 01 timezone usage binary-c-long.
 01 daylight usage binary-long.


 call "CBL_GC_HOSTED" stdin "stdin"
 call "CBL_GC_HOSTED" errno "errno"
 set address of err to errno

 call "fgets" using buffer by value 80 stdin returning got
 if got equal null then
     display "stdin error: " err upon syserr
     move 0 to err
 end-if

 set environment "TZ" to "PST8PDT"
 call "tzset" returning omitted
 call "CBL_GC_HOSTED" tzname "tzname" returning result
 if result equal zero and tzname not equal null then
     set address of tznames to tzname
     if tzs(1) not equal null then
         call "printf" using
             by content "first tzname: %s" & x"0a00"
             by value tzs(1)
     end-if
 end-if

The CBL_GC_HOSTED system call makes it just that little bit easier to interact with POSIX and C from GnuCOBOL.

3.15   How do you print to printers with GnuCOBOL?

GnuCOBOL and COBOL in general does not directly support printers. That role is delegated to the operating system. Having said that, there are a few ways to get data to a printer.

3.15.1   printing with standard out

Writing directly to standard out, as explained in Can GnuCOBOL be used to write command line stdin, stdout filters? and then simply piping to lpd should usually suffice to get text to your printer.

$ ./cobprog | lp
$ ./yearend | lp -d $PRESIDENTSPRINTER

Don’t try the above with the DISPLAY verb; use WRITE TO stdout, with stdout selected and assigned to the DISPLAY name.

3.15.2   calling the system print

Files can be routed to the printer from a running program with sequences such as

CALL "SYSTEM"
    USING "lp os-specific-path-to-file"
    RETURNING status
END-CALL

3.15.5   Jim Currey’s prtcbl

Jim kindly donated this snippet. One of his earliest efforts establishing a base of GnuCOBOL resources. prtcbl produces source code listing with results piped to a printer.

A few customizations. This version requires a change to a filename for printer control, location of copybooks, and possible changes to the system lp command line.

Stash a print setup string in the file so named. The program prompts for input, output and printer.

Jim pointed out that this was early attempts with OpenCOBOL as a tool to support better in house development, and was nice enough to let me reprint it.

GCobol IDENTIFICATION DIVISION.
       PROGRAM-ID. PRTCBL.
      *AUTHOR. J C CURREY.
      ************************************************************
      *      PRINTS A COBOL SOURCE FILE WITH IT'S COPY BOOKS     *
      *                                                          *
      *   VERSION 001--ORIGINAL VERSION                          *
      *                 3/26/2009--J C CURREY                    *
      *                                                          *
      *           002--ADDS .CPY (CAPS) IF .cpy FAILS TO FIND    *
      *                  FILE AND EXPANDS INPUT TO 132 CHARACTERS*
      *                 4/09/2009--J C CURREY                    *
      *                                                          *
      *           003--ADDS NOLIST AND LIST SUPPORT (NOTE NOT    *
      *                  SUPPORTED BY OPENCOBOL COMPILER)        *
      *                  **NOLIST IN COL 7-14 TURNS OFF LISTING  *
      *                  **LIST IN COL 7-12 TURNS ON LISTING     *
      *                 4/22/2009--J C CURREY                    *
      *                                                          *
      *           004--ADDS SUPPORT FOR /testing-set-1/copybooks *
      *                Copybooks are searched for first in the   *
      *                local directory and if not found, then in *
      *                /testing-set-1/copybooks                  *
      *                 5/7/2009--J C CURREY                     *
      *                                                          *
      *           005--CORRECTS MISSING LINE ISSUE ON PAGE BREAKS*
      *                IN THE COPY FILE PRINTING SECTION.        *
      *                1285451--SANDY DOSS                       *
      *                06/19/2009--JEREMY MONTOYA                *
      *                                                          *
      *           006--USES EXTERNAL PCL CODE FILE TO INSERT PCL *
      *                CODE INTO PRINT FILE FOR FORMATTING.      *
      *                1330505--JIM CURREY                       *
      *                12/14/2009--PETE MCTHOMPSON               *
      ************************************************************
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
121409     SELECT FORMAT-FILE ASSIGN TO WS-NAME-FORMAT-FILE
121409       ORGANIZATION IS LINE SEQUENTIAL.
           SELECT PRINT-FILE ASSIGN TO WS-NAME-PRINT-FILE
             ORGANIZATION IS LINE SEQUENTIAL.
           SELECT INPUT-FILE ASSIGN TO WS-NAME-INPUT-FILE
             ORGANIZATION IS LINE SEQUENTIAL
             FILE STATUS IS WS-INPUT-FILE-STATUS.
           SELECT COPY-FILE ASSIGN TO WS-NAME-COPY-FILE
             ORGANIZATION IS LINE SEQUENTIAL
             FILE STATUS IS WS-COPY-FILE-STATUS.
       DATA DIVISION.
       FILE SECTION.
      *
       FD  PRINT-FILE.
121409 01  FORMAT-LINE                         PIC X(140).
       01  PRINT-LINE.
           05  OR-LINE-NUMBER                  PIC Z(6).
           05  OR-FILLER-1                     PIC XX.
           05  OR-TEXT                         PIC X(132).
121409*
121409 FD  FORMAT-FILE.
121409 01  FORMAT-RECORD                       PIC X(140).
      *
       FD  INPUT-FILE.
       01  INPUT-RECORD.
           05  IR-BUFFER                       PIC X(132).

       FD  COPY-FILE.
       01  COPY-RECORD.
           05  CR-BUFFER                       PIC X(132).
      **NOLIST
      * THIS IS ANOTHER LINE
      **LIST
      *
       WORKING-STORAGE SECTION.
      ****************************************************
      *   CONSTANTS, COUNTERS AND WORK AREAS             *
      ****************************************************
       01  WS-NAME-PROGRAM                     PIC X(12) VALUE
121409                                            "prtcbl   006".
       01  WS-NO-PARAGRAPH                     PIC S9(4) COMP.
       01  WS-I                                PIC S9(4) COMP.
       01  WS-J                                PIC S9(4) COMP.
       01  WS-K                                PIC S9(4) COMP.
       01  WS-NAME-PRINT-FILE                  PIC X(64) VALUE SPACES.
       01  WS-NAME-INPUT-FILE                  PIC X(64) VALUE SPACES.
       01  WS-INPUT-FILE-STATUS                PIC XX VALUE "00".
050709 01  WS-NAME-COPY-FILE                   PIC X(128) VALUE SPACES.
050709 01  WS-HOLD-NAME-COPY-FILE              PIC X(128) VALUE SPACES.
121409 01  WS-NAME-FORMAT-FILE                 PIC X(128) VALUE SPACES.
       01  WS-COPY-FILE-STATUS                 PIC XX VALUE "00".
       01  WS-LINE-PRINTER-NAME                PIC X(16) VALUE SPACES.
       01  WS-LINE-NUMBER                      PIC S9(6) COMP
                                                    VALUE ZERO.
       01  WS-PAGE-LINE-COUNTER                PIC S9(4) COMP
                                                    VALUE 999.
       01  WS-PAGE-NUMBER                      PIC S9(4) COMP
                                                    VALUE ZERO.
       01  WS-PRINT-COMMAND                    PIC X(128).
      *
       01  WS-ESCAPE-CHARACTER                 PIC X VALUE X"1B".
      *
       01  WS-HEADING-LINE                     PIC X(132).
       01  WS-CURRENT-DATE                     PIC X(21).
       01  WS-ED4S                             PIC ZZZZ-.
042209 01  WS-SWITCH-PRINT                     PIC X VALUE SPACE.
      ****************************************************************
      *                PROCEDURE DIVISION                            *
      ****************************************************************
       PROCEDURE DIVISION.
       0000-MAIN SECTION.
           PERFORM 1000-INITIALIZATION THRU 1990-EXIT.
           PERFORM 2000-PROCESS THRU 2990-EXIT.
           PERFORM 9000-END-OF-PROGRAM THRU 9990-EXIT.
           STOP RUN.
      ****************************************************************
      *               INITIALIZATION                                 *
      ****************************************************************
       1000-INITIALIZATION.
           MOVE 1000 TO WS-NO-PARAGRAPH.
           DISPLAY "I) ", WS-NAME-PROGRAM, " BEGINNING AT--"
             FUNCTION CURRENT-DATE.
       1002-GET-INPUT-FILE.
           DISPLAY "A) ENTER INPUT-FILE NAME " WITH NO ADVANCING.
           ACCEPT WS-NAME-INPUT-FILE.
           OPEN INPUT INPUT-FILE.
           IF WS-INPUT-FILE-STATUS IS EQUAL TO 35
             DISPLAY "W) INPUT FILE NOT FOUND"
             GO TO 1002-GET-INPUT-FILE.
           DISPLAY "A) ENTER PRINT-FILE (WORK FILE) NAME "
             WITH NO ADVANCING.
           ACCEPT WS-NAME-PRINT-FILE.
           DISPLAY "A) ENTER PRINTER NAME " WITH NO ADVANCING.
           ACCEPT WS-LINE-PRINTER-NAME.
           OPEN OUTPUT PRINT-FILE.
121409     MOVE "laserjet_113D.txt" TO WS-NAME-FORMAT-FILE.
121409     OPEN INPUT FORMAT-FILE.
121409 1010-OUTPUT-PCL-CODES.
121409     READ FORMAT-FILE NEXT RECORD AT END GO TO 1020-FORMAT-EOF.
121409     MOVE FORMAT-RECORD TO FORMAT-LINE.
121409     WRITE FORMAT-LINE.
121409     GO TO 1010-OUTPUT-PCL-CODES.
121409 1020-FORMAT-EOF.
121409     CLOSE FORMAT-FILE.
       1990-EXIT.
           EXIT.
      **************************************************************
      *                 DETAIL SECTION                             *
      **************************************************************
       2000-PROCESS.
           MOVE 2000 TO WS-NO-PARAGRAPH.
           READ INPUT-FILE NEXT RECORD AT END GO TO 2990-EXIT.
           ADD 1 TO WS-LINE-NUMBER.
           IF WS-PAGE-LINE-COUNTER IS GREATER THAN 112
             PERFORM 2800-HEADINGS THRU 2890-EXIT.
           MOVE WS-LINE-NUMBER TO OR-LINE-NUMBER.
           MOVE SPACES TO OR-FILLER-1.
           MOVE INPUT-RECORD TO OR-TEXT.
042209     IF IR-BUFFER (7:6) IS EQUAL TO "**LIST"
042209       MOVE "Y" TO WS-SWITCH-PRINT.
042209     IF WS-SWITCH-PRINT IS EQUAL TO "N"
042209       THEN NEXT SENTENCE
042209       ELSE WRITE PRINT-LINE
042209            ADD 1 TO WS-PAGE-LINE-COUNTER.
042209      IF IR-BUFFER (7:8) IS EQUAL TO "**NOLIST"
042209       MOVE "N" TO WS-SWITCH-PRINT.
           IF IR-BUFFER (7:1) IS EQUAL TO "*" GO TO 2000-PROCESS.
           MOVE 1 TO WS-I.
       2010-COMPARE-LOOP.
           IF IR-BUFFER (WS-I:2) IS EQUAL TO "*>" GO TO 2090-ENDER.
           IF IR-BUFFER (WS-I:6) IS EQUAL TO " COPY " GO TO 2020-COPY.
           ADD 1 TO WS-I.
           IF WS-I IS LESS THAN 73 GO TO 2010-COMPARE-LOOP.
           GO TO 2000-PROCESS.
       2020-COPY.
           SUBTRACT 1 FROM WS-LINE-NUMBER.
           ADD 6 TO WS-I.
           MOVE 1 TO WS-J.
           MOVE SPACES TO WS-NAME-COPY-FILE.
       2022-MOVE-LOOP.
           IF IR-BUFFER (WS-I:1) IS EQUAL TO SPACE
             GO TO 2030-OPEN-COPYFILE.
           IF IR-BUFFER (WS-I:1) IS EQUAL TO "."
             MOVE ".cpy" to WS-NAME-COPY-FILE (WS-J:4)
               GO TO 2030-OPEN-COPYFILE.
           MOVE IR-BUFFER (WS-I:1) TO WS-NAME-COPY-FILE (WS-J:1).
           ADD 1 TO WS-I, WS-J.
           IF WS-I IS GREATER THAN 73
             OR WS-J IS GREATER THAN 64
               THEN MOVE "**PROBLEM WITH.COPY STATEMENT ABOVE**"
                      TO OR-TEXT
                    WRITE PRINT-LINE
                    ADD 1 TO WS-PAGE-LINE-COUNTER
                    GO TO 2000-PROCESS.
           GO TO 2022-MOVE-LOOP.
       2030-OPEN-COPYFILE.
           OPEN INPUT COPY-FILE.
           IF WS-COPY-FILE-STATUS IS NOT EQUAL TO "00"
040909       MOVE ".CPY" TO WS-NAME-COPY-FILE (WS-J:4)
040909       OPEN INPUT COPY-FILE
040909       IF WS-COPY-FILE-STATUS IS NOT EQUAL TO "00"
050709         MOVE WS-NAME-COPY-FILE TO WS-HOLD-NAME-COPY-FILE
050709         STRING "/testing-set-1/copybooks/"
050709           WS-HOLD-NAME-COPY-FILE
050709             INTO WS-NAME-COPY-FILE
      *     DISPLAY "D) AT.COPY FILE OPEN NAME=\", WS-NAME-COPY-FILE, "\"
050709         OPEN INPUT COPY-FILE
050709           IF WS-COPY-FILE-STATUS IS NOT EQUAL TO "00"
050709             ADD 25 TO WS-J
050709             MOVE ".cpy" TO WS-NAME-COPY-FILE (WS-J:4)
      *     DISPLAY "D) AT.COPY FILE OPEN NAME=\", WS-NAME-COPY-FILE, "\"
050709             OPEN INPUT COPY-FILE
050709             IF WS-COPY-FILE-STATUS IS NOT EQUAL TO "00"
050709               MOVE "***COPY FILE ABOVE NOT FOUND***" TO OR-TEXT
050709               WRITE PRINT-LINE
050709               ADD 1 TO WS-LINE-NUMBER
050709               ADD 1 TO WS-PAGE-LINE-COUNTER
050709               GO TO 2000-PROCESS
050709             END-IF
050709           END-IF
040909       END-IF
040909     END-IF.
       2032-PRINT-LOOP.
           READ COPY-FILE NEXT RECORD AT END GO TO 2039-EOF.
           ADD 1 TO WS-LINE-NUMBER.
061909*    MOVE WS-LINE-NUMBER TO OR-LINE-NUMBER.
061909*    MOVE SPACES TO OR-FILLER-1.
061909*    MOVE COPY-RECORD TO OR-TEXT.
           IF WS-PAGE-LINE-COUNTER IS GREATER THAN 112
             PERFORM 2800-HEADINGS THRU 2890-EXIT.
061909     MOVE WS-LINE-NUMBER TO OR-LINE-NUMBER.
061909     MOVE SPACES TO OR-FILLER-1.
061909     MOVE COPY-RECORD TO OR-TEXT.
042209     IF CR-BUFFER (7:6) IS EQUAL TO "**LIST"
042209       MOVE "Y" TO WS-SWITCH-PRINT.
042209     IF WS-SWITCH-PRINT IS EQUAL TO "N"
042209       THEN NEXT SENTENCE
042209       ELSE WRITE PRINT-LINE
042209            ADD 1 TO WS-PAGE-LINE-COUNTER.
042209      IF CR-BUFFER (7:8) IS EQUAL TO "**NOLIST"
042209       MOVE "N" TO WS-SWITCH-PRINT.
           GO TO 2032-PRINT-LOOP.
       2039-EOF.
           CLOSE COPY-FILE.
042209     MOVE "Y" TO WS-SWITCH-PRINT.
       2090-ENDER.
           GO TO 2000-PROCESS.
      *
      *    PAGE HEADINGS
      *
       2800-HEADINGS.
           INITIALIZE PRINT-LINE.
           ADD 1 TO WS-PAGE-NUMBER.
           MOVE FUNCTION CURRENT-DATE TO WS-CURRENT-DATE.
           MOVE WS-NAME-INPUT-FILE TO PRINT-LINE.
           MOVE WS-PAGE-NUMBER TO WS-ED4S.
           MOVE "PAGE" TO PRINT-LINE (66:4).
           MOVE WS-ED4S TO PRINT-LINE (71:4).
           MOVE WS-CURRENT-DATE (5:2) TO PRINT-LINE (80:2).
           MOVE "/" TO PRINT-LINE (82:1).
           MOVE WS-CURRENT-DATE (7:2) TO PRINT-LINE (83:2).
           MOVE "/" TO PRINT-LINE (85:1).
           MOVE WS-CURRENT-DATE (1:4) TO PRINT-LINE (86:4).
           MOVE WS-CURRENT-DATE (9:2) TO PRINT-LINE (92:2).
           MOVE ":" TO PRINT-LINE (94:1).
           MOVE WS-CURRENT-DATE (11:2) TO PRINT-LINE (95:2).
           MOVE ":" TO PRINT-LINE (97:1).
           MOVE WS-CURRENT-DATE (13:2) TO PRINT-LINE (98:2).
           IF WS-PAGE-NUMBER IS EQUAL TO 1
             THEN WRITE PRINT-LINE
             ELSE WRITE PRINT-LINE AFTER ADVANCING PAGE.
           INITIALIZE PRINT-LINE.
           WRITE PRINT-LINE.
           MOVE 4 TO WS-PAGE-LINE-COUNTER.
       2890-EXIT.
           EXIT.
      *
      *    END OF JOB
      *
       2990-EXIT.
           EXIT.
      ****************************************************************
      *             TERMINATION                                      *
      ****************************************************************
       9000-END-OF-PROGRAM.
           MOVE 9000 TO WS-NO-PARAGRAPH.
           CLOSE INPUT-FILE.
           CLOSE PRINT-FILE.
121409*    STRING "lp -d " DELIMITED BY SIZE,
121409*      WS-LINE-PRINTER-NAME DELIMITED BY SIZE,
121409*      "-o sides=two-sided-long-edge " DELIMITED BY SIZE,
121409*      "-o lpi=11 -o cpi=18 -o page-left=34 " DELIMITED BY SIZE,
121409*      WS-NAME-PRINT-FILE DELIMITED BY SIZE
121409*        INTO WS-PRINT-COMMAND.
           STRING "lp -d " DELIMITED BY SIZE,
             WS-LINE-PRINTER-NAME DELIMITED BY SIZE,
             "-o raw " DELIMITED BY SIZE,
             WS-NAME-PRINT-FILE DELIMITED BY SIZE
               INTO WS-PRINT-COMMAND.
           CALL "SYSTEM" USING WS-PRINT-COMMAND.
           DISPLAY "I) " WS-NAME-PROGRAM " COMPLETED NORMALLY AT--"
               FUNCTION CURRENT-DATE.
       9990-EXIT.
           EXIT.

3.16   Can I run background processes using GnuCOBOL?

Absolutely. Using the CALL "SYSTEM" service. Some care must be shown to properly detach the input output handles, and to instruct the processes to ignore hangup signals along with the “run in a background subshell” control.

CALL "SYSTEM"
    USING
        "nohup whatever 0</dev/null 1>mystdout 2>mystderr &"
    RETURNING result
END-CALL

That runs whatever in the background, detaches stdin, sends standard output to the file mystdout and standard error to mystderr.

The above example is for POSIX_ shell operating systems. As always, the commands sent through SYSTEM are VERY operating system dependent.

3.17   Is there GnuCOBOL API documentation?

Absolutely. Sort of. And it’s beautiful, complete and awe inspiring.

Dimitri van Heesch’s 1.7.4 release of Doxygen, http://www.doxygen.org was used to produce http://opencobol.add1tocobol.com/doxy/ and along with Gary’s OCic.cbl http://opencobol.add1tocobol.com/doxyapp/ to highlight the absolutely beautiful compiler and application documentation available for GnuCOBOL now. These pages were produced with very little effort with only a few small tweaks to the Doxygen generated Doxyfile (to turn on all files, and to generate call graphs). The sample pass produces a 1400 page beauty of a reference manual in PDF generated from the Doxygen LaTex output. 2950 pages for the sample application run.

GnuCOBOL ships as a developer tarball and Doxygen was let loose on the source tree after a ./configure and make pass. When the -C output of Gary Cutler’s OCic.cbl was placed into the tree, the output includes the call graphs that exercise some of the GnuCOBOL run-time library. This application level documentation is world class.

Regarding the above “sort of”. This was a near effortless use of Doxygen. GnuCOBOL was not touched and the sources have no explicit Doxygen tags. It also excludes many of the automake, libtool, bison and flex source files. Even still, beautiful. The compiler API is now an easy grok, and application level documentation (doxyapp using OCic.cbl as a sample) should satisfy the world’s most ruthless code auditor and meticulous development team lead.

See http://opencobol.add1tocobol.com/doxy/d2/dd4/structcb__field.html for a tantalizing sample of cb_field collaboration diagram and completeness of source code coverage. See http://opencobol.add1tocobol.com/doxyapp/d4/da8/OCic_8c.html for a view of how Doxygen handles the application level documentation. All for free.

3.18   How do I use LD_RUN_PATH with GnuCOBOL?

LD_RUN_PATH can be a saving grace for developers that want to build GnuCOBOL on hosted environments. LD_RUN_PATH is similar to LD_LIBRARY_PATH but builds the shared library path into cobc and then all of the binaries compiled with cobc. That means you can cherry pick the link loader paths when you build GnuCOBOL in a way that can add support for unsupported host features.

If you want a recent version of ncurses on your hosting service, but don’t have root permissions, you can build it into one of your own directories then

EXPORT LD_RUN_PATH=mylibdir
./configure ; make ; make install

to build your GnuCOBOL. All compiles with cobc will now include mylibdir during compiles, and better yet, the binaries produced will also include mylibdir in the search path at run-time.

If you don’t have RECORD_PATH in your cobc then you can simply compile with

LD_RUN_PATH=mylibdir cobc -x nextbigthing.cob

to achieve similar results.

With the CGI interface, see How do I use GnuCOBOL for CGI?, you can now build up a complete web side solution using GnuCOBOL with little worry about being stuck on link library dependencies or running scripts to setup any path variables before safely using your cgi-bin binaries.

LD_RUN_PATH is magical. It also avoids many security problems that can occur if you rely on LD_LIBRARY_PATH user environment settings. Your cobc will have your search path and not some /home/badusers trickery settings as LD_RUN_PATH searches come before LD_LIBRARY_PATH. Relying on LD_LIBRARY_PATH is deemed a Don’t do by some experts. LD_RUN_PATH is a much safer bet.

3.19   What GNU build tool options are available when building GnuCOBOL?

The sources for the GnuCOBOL compiler follows GNU standards whenever possible. This includes being built around the GNU build system.

3.19.1   Basics

From an end-user perspective, what this means is that the source code distributions follow these basic steps:

tar xvf open-cobol-1.1.tar.gz
cd open-cobol-1.1
./configure
make
make check
sudo make install
sudo ldconfig

But that is just scratching the surface of the possibilities. See What are the configure options available for building GnuCOBOL? for the first steps with ./configure.

3.19.2   Out of tree builds

Next up, GnuCOBOL fully supports out-of-source-tree builds.

From Roger:

I mentioned in the past the preferred way of doing
a configure/build ie. Out-of-source-tree build.

eg.
We have OC 2.0 in /home/open-cobol-2.0

We want to test -
OC with BDB
OC with vbisam
OC without db (ISAM)

mkdir /home/oc20110710bdb
cd /home/oc20110710bdb
/home/open-cobol-2.0/configure --enable-debug
make
make check
cd tests
cd cobol85
# <Get newcob.val - per README>
make test

mkdir /home/oc20110710vbisam
cd /home/oc20110710vbisam
/home/open-cobol-2.0/configure --enable-debug --with-vbisam
make
make check
cd tests
cd cobol85
# <Get newcob.val - per README>
make test

mkdir /home/oc20110710nodb
cd /home/oc20110710nodb
/home/open-cobol-2.0/configure --enable-debug --without-db
make
make check
cd tests
cd cobol85
# <Get newcob.val - per README>
make test

For the last example both the OC and ANSI85 tests have been adjusted
to cater for lack of ISAM functionality.

To set your current environment to compile/execute from any of the above
(ie. without doing a "make install" from any directory), then
either "source" or execute as part of current environment
(with . ) the following files from the build directory -
tests/atconfig
tests/atlocal

(Note in that order)

So eg.
. /home/oc20110710vbisam/tests/atconfig
. /home/oc20110710vbisam/tests/atlocal

will set compiler/runtime to this environment in the current shell.

Note that both the OC tests and the ANSI85 tests do this internally
(Fairly obvious otherwise we would not be testing the right thing).

Of course, from any of the above example directories you can do
a final "make install".

This can be made a lot easier to remember by using a shell function.

Add the following to $HOME/.bashrc (and edit the path names).

# multiple versions of GnuCOBOL, when built from source
# ### UPDATE source PATHNAMES to match local installation ###
use-cobol () {
    local ROOTPATH="$HOME"/builds
    case "$1" in
    2\.0 | 2)
         source "$ROOTPATH"/branches/gnu-cobol-2.0/tests/atconfig
         source "$ROOTPATH"/branches/gnu-cobol-2.0/tests/atlocal
         ;;
    reportwriter | rw)
         source "$ROOTPATH"/branches/reportwriter/tests/atconfig
         source "$ROOTPATH"/branches/reportwriter/tests/atlocal
         ;;
    cpp | c\+\+)
         source "$ROOTPATH"/branches/gnu-cobol-cpp/tests/atconfig
         source "$ROOTPATH"/branches/gnu-cobol-cpp/tests/atlocal
         ;;
    fileiorewrite )
         source "$ROOTPATH"/branches/fileiorewrite/tests/atconfig
         source "$ROOTPATH"/branches/fileiorewrite/tests/atlocal
         ;;
    release | gnucobol)
         source "$ROOTPATH"/trunk/gnu-cobol/tests/atconfig
         source "$ROOTPATH"/trunk/gnu-cobol/tests/atlocal
         ;;
    *)
         echo "Use use-cobol 2 rw cpp fileiorewrite or release"
         ;;
    esac
}

And now, it is a simpler:

prompt$ use-cobol 2.0
prompt$ use-cobol reportwriter
prompt$ use-cobol c++

You could also add strings to the case statement patterns to match personal taste, as in 2\.0 | 2 | simon) and use:

prompt$ use-cobol simon
prompt$ use-cobol ron
prompt$ use-cobol sergey
prompt$ use-cobol joe
prompt$ use-cobol experiment

if that is easier to remember. And use what ever name for the use-cobol function that you please.

Please note that because of the way shell scripts work, those atconfig and atlocal lines don’t work from an external script. You have to invoke the source shell command from the current shell, and shell functions do that.

If you like to keep your ~/.bashrc clean, then source in the definition of the function. As long as the function runs from the current shell and not a sub-shell it will work, otherwise all the environment settings are forgotten, as the environment is never passed up to a parent process, only down to children.

3.19.3   Autotest options

By developing the GnuCOBOL system around the GNU build tools, developers receive a great many options for free.

make check can include TESTSUITEFLAGS.

The TESTSUITEFLAGS allows for options that include:

  • make check TESTSUITEFLAGS="--list" to list the available tests and descriptions
  • "--verbose" to show a little more information during the tests
  • "--jobs=n" to run n tests in parallel. On multi core systems, the speed up is fairly dramatic. For 425 tests, normally 1 minute 22 seconds, --jobs=4 ran in 36 seconds (on a small little AMD Athlon(tm) II X2 215 Processor). The more cores, the more dramatic the improvement.

3.20   Why don’t I see any output from my GnuCOBOL program?

This is actually a frequently asked question, and it usually has the same answer.

GnuCOBOL uses the Curses and NCurses packages for advanced terminal features and SCREEN SECTION handling. This uses stdscr for input and output, and not the standard CONSOLE, SYSIN, SYSOUT character interface modes. One feature of the Curses handler is the concept of a secondary screen buffer, which is erased during initialization and then disappears at rundown. This can happen so fast on short display programs that it looks like nothing happens.

program-id. helloat.
DISPLAY "Hello, world" LINE 5 COLUMN 5
goback.

Running that code will cause the Curses package to initialize a secondary buffer, display the Hello string, then immediately restore the original screen buffer during goback. It will look like nothing is output when ./helloat is run. There are a few fixes for this.

  • delay rundown with a CALL "C$SLEEP" USING 5 END-CALL
  • ACCEPT OMITTED which will wait for a carriage return (GnuCOBOL 2.0)
  • ACCEPT unused-variable can also be used to pause a program before exit
  • or even better, dump the secondary buffer from all Curses screen handling

(ACCEPT OMITTED actually waits for any “terminating” keyboard input, carriage return, function keys, and some others).

The last option from the above list, removing the secondary buffer, is discussed below.

3.20.1   SMCUP and RMCUP

https://blogs.oracle.com/samf/entry/smcup_rmcup_hate is a great article that discusses, and sledgehammer fixes, the curses init screen clearing issue, leaving output on the stdout terminal, not an alternate screen.

First to find out the actual terminal capabilities, (and what control file is going to change):

$ infocmp | head -2

shows:

# Reconstructed via infocmp from file: /home/btiffin/.terminfo/x/xterm-256color
xterm-256color|xterm with 256 colors,

There is some voodoo with infocmp (and tic, the terminal information compiler), to worry about. By default, infocmp reads local user files, but this change can also effect the entire system, if run as root.

Using a super user context:

[btiffin@localhost junk]$ sudo infocmp | head -2
# Reconstructed via infocmp from file: /usr/share/terminfo/x/xterm-256color
xterm-256color|xterm with 256 colors,

gives us the system file.

After creating a just in case copy of /usr/share/terminfo/x/xterm-256color it is time to get rid of the alternate stdscr.

$ infocmp >xterm.terminfo
$ vi xterm.terminfo
$ # get rid of smcup= and rmcup= upto and including the comma
$ tic xterm.terminfo

in my case, the temporary xterm.terminfo looked like:

...
rin=\E[%p1%dT, rmacs=\E(B, rmam=\E[?7l, rmcup=\E[?1049l,
rmir=\E[4l, rmkx=\E[?1l\E>, rmm=\E[?1034l, rmso=\E[27m,
rmul=\E[24m, rs1=\Ec, rs2=\E[!p\E[?3;4l\E[4l\E>, sc=\E7,
setab=\E[4%p1%dm, setaf=\E[3%p1%dm,
setb=\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m,
setf=\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m,
sgr=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m,
sgr0=\E(B\E[m, smacs=\E(0, smam=\E[?7h, smcup=\E[?1049h,
...

and becomes:

...
rin=\E[%p1%dT, rmacs=\E(B, rmam=\E[?7l,
rmir=\E[4l, rmkx=\E[?1l\E>, rmm=\E[?1034l, rmso=\E[27m,
rmul=\E[24m, rs1=\Ec, rs2=\E[!p\E[?3;4l\E[4l\E>, sc=\E7,
setab=\E[4%p1%dm, setaf=\E[3%p1%dm,
setb=\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m,
setf=\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m,
sgr=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m,
sgr0=\E(B\E[m, smacs=\E(0, smam=\E[?7h,
...

rmcup and smcup edited out. (The end bits of the first and last lines of the listing.)

After the tic command completes, there is a shiny new local /home/btiffin/.terminfo/x/xterm-256color compiled terminfo file that has no alternate terminal screen capabilities. All output will happen in the primary screen buffer. I see no downside to this.

As long as you don’t run the terminal info compiler, tic, as root, the files in /usr/share/terminfo/... will still be the originals, and a new local copy is made. tic will overwrite the system file if it can, but will move on and create a local compiled file, if it cannot write to the system. Until you are sure, best to run this locally and not as the superuser.

The script in Sam’s blog, mentioned above, will alleviate doing this manually every time the system updates the terminfo database.

So now, code like the following that displays data on line 2, column 12 and line 3, column 13

identification division.
program-id. helloscreen.
procedure division.
display "Hello, world" at 0212
display "Goodbye, smcup/rmcup" at 0313
goback.
end program helloscreen.

and then the command below; which still blanks the screen, but now leaves output on the terminal after goback.

[btiffin@home forum]$ ./helloscreen

       Hello, world
        Goodbye, smcup/rmcup
[btiffin@home forum]$

GnuCOBOL displays things using advanced terminal capabilities, but leaves the data on screen after image exit.

Never worry about smcup/rmcup hate on curses init again. Not just GnuCOBOL and curses, but vi, less, man and any other alternate screen application. For the win. This change effects old school TE TI termcap calls too.

Curses will still play havoc with screen section programs in pipes; as stdin, stdout are a little special with curses involved. This is a minor annoyance that won’t come up as often and piping screen interactive programs has always been laden in voodoo anyway.

3.21   What are the GnuCOBOL compiler run-time limits?

This may well be a long term entry, updated as facts come in

Some limits are only found by careful examination of code.

For instance, field names are limited to 31 characters, unless -frelax-syntax is used in which case the maximum is 61.

Some limits are enumerated.

3.21.1   libcob/common.h

From libcob/common.h May 2014

/* Buffer size definitions */

#define COB_MINI_BUFF           256
#define COB_SMALL_BUFF          1024
#define COB_NORMAL_BUFF         2048
#define COB_FILE_BUFF           4096
#define COB_MEDIUM_BUFF         8192
#define COB_LARGE_BUFF          16384
#define COB_MINI_MAX            (COB_MINI_BUFF - 1)
#define COB_SMALL_MAX           (COB_SMALL_BUFF - 1)
#define COB_NORMAL_MAX          (COB_NORMAL_BUFF - 1)
#define COB_FILE_MAX            (COB_FILE_BUFF - 1)
#define COB_MEDIUM_MAX          (COB_MEDIUM_BUFF - 1)
#define COB_LARGE_MAX           (COB_LARGE_BUFF - 1)

/* Perform stack size */
#define COB_STACK_SIZE          255

/* Maximum size of file records */
#define MAX_FD_RECORD           65535

/* Maximum number of parameters */
#define COB_MAX_FIELD_PARAMS    36

/* Maximum number of field digits */
#define COB_MAX_DIGITS          38

/* Max digits in binary field */
#define COB_MAX_BINARY          39

/* Maximum number of cob_decimal structures */
#define COB_MAX_DEC_STRUCT      32

/* Maximum group and single field size */
#define COB_MAX_FIELD_SIZE      268435456

...

How configurable are these, when needs press? Change developer would need to comb over the run-time, to make sure there aren’t hidden assumptions.

For instance, MAX_FIELD_PARAMS, is included in a field by field copy in libcob/call.c indexed by number. Change to that value would need other source changes in support.

Umm, start mucking around with MAX_DIGITS, and expect to comb over a LOT of GNU Cobol source. The first 500 lines of libcob/common.h is optimization macros, let alone the hooks in numeric.c, move, and on and on into the big blue. Or, read this, go, “oh yeah? I can write that.” and show me up while enhancing the world.

COBOL fields (and group total) can be 258 megabytes, COB_MAX_FIELD_SIZE.

MAX_FD_RECORD limits are likely entangled by external forces, and again, more reading if you want to change this.

Terminal buffer is MEDIUM_BUFF, 8K, as is the free form line limit.

Environment variable lookup space is LARGE_BUFF, so 16K.

Details are usually gleaned with a grep across the source tree.

3.22   What are the GnuCOBOL run-time environment variables?

COB_LEGACY
Effect screen attributes for non input fields when set to Y.
COB_LIBRARY_PATH
Augments the run time DSO search path.
COB_LS_NULLS
Inserts a 0 byte before any x value less than x‘20’ when set to Y. From asking around, this is very likely related to legacy print file support. I may be rumour mongering, but I trust the sources.
COB_LS_FIXED
Writes to LINE SEQUENTIAL files will be padded with spaces to the FD length when set to Y.
COB_PRE_LOAD
A colon separated list of DSO names. This comes in very handy when coming to grips with both foreign libraries and GnuCOBOL dynamic shared object files.
COB_SET_DEBUG
Turns on >>D lines when set to Y.
COB_SYNC
Explicit flush after writes when set.

GnuCOBOL 1.1 COB_SYNC values:

    none of the values below: don't do extra synch - the system (and
additional for indexed files the library used) decide when the buffer
should be written to the file (in general keys are stored more often and
if locking is active more is done) - it is guaranteed to be done on
CLOSE... --> this is the standard and is normally completely fine.

    Y or y: after all file-changes (WRITE, REWRITE, DELETE) do an extra
synch of the indexed files via the library, all other files will receive
an fflush()/)

    P or p: additional send fsync() to all files to be physically written
to disk and wait until this is finished (real slow)

GnuCOBOL 2.0 settings

    false values: don't do extra synch - the system (and additional for
indexed files the library used) decide when the buffer should be written
to the file (in general keys are stored more often and if locking is
active more is done) - it is guaranteed to be done on CLOSE... --> this is
the standard and is normally completely fine.

    true values or P: after all sucessful file commands nearly identical
to the P option of GnuCOBOL 1.1: if fdatasync() is available use this
(force data write and wait for it but don't force writing of metadata like
last access/write stamps), otherwise use fsync

There is an extreme performance penalty with COB_SYNC set. Be warned.

The setting was added for systems that need files to be immediately written because of likely power outages without UPS, or similar concerns, not for file sharing issues.

For the GnuCOBOL-reportwriter branch, Ron has added code to allow COB_SYNC settings on a per-file basis, but until those changes are merged into GnuCOBOL 2.0, the COB_SYNC setting is global, and effects all file write operations during a run.

DB_HOME
Used by Berkeley DB for file sharing, pointing to file directory.
ESC_DELAY
For ncurses, SCREEN SECTION, detection of the ESC key is delayed, allowing for detection of extended keyboard keys, ala Function and cursor keys. Historically, on slow serial lines of old, this delay was set to a noticable value, approaching one second. Now, the delay can be safely set to less than 100 milliseconds, roughly the threshold of human noticeability. export ESC_DELAY=25 being a sane choice.
OCREPORTDEBUG
This is Ron’s, it may go away
  • COB_BELL
  • COB_DISABLE_WARNINGS
  • COB_ENV_MANGLE
  • COB_FILE_PATH
  • COB_LS_USES_CR
  • COB_REDIRECT_DISPLAY
  • COB_SCREEN_EXCEPTIONS
  • COB_SCREEN_ESC
  • COB_SET_TRACE
  • COB_SORT_CHUNK
  • COB_SORT_MEMORY
  • COB_TIMEOUT_SCALE
  • COB_TRACE_FILE
  • COB_UNIX_LF
  • COB_VARSEQ_FORMAT
  • LOGNAME
  • TEMP
  • TMP
  • TMPDIR
  • USERNAME

3.23   What are the differences between OpenCOBOL 1.1 and GnuCOBOL 1.1?

Thanks to Simon Sobisch, for putting these back port ChangeLog notes together. Nice

the differences of OpenCOBOL 1.1 and GnuCOBOL 1.1 (this release had the temporary name GNU Cobol, but I’ll stick to the newer one when referencing it

3.23.1   General:

  • test suite and ANSI 85 tests will pass if no ISAM is configured, too (ISAM tests are skipped in this case)
  • configure: Added check for using GMP library, better checks for BDB
  • included CBL_OC_DUMP for hex-dumping
  • security issue: following CVE-2009-4029 distribution tarballs are created with mode 755, not 777
  • tarstamp.h includes a printable definition for COB_NUM_TAR_DATE & COB_NUM_TAR_TIME
  • name change shows it’s really free, not only open-source (like others) and it shows it has a quality that’s worth to be GNU
  • credits to more of the people involved
  • minor fixes of typing errors
  • support for icc, better support for IBM390, MSC, BORLANDC, WATCOMC
  • remove extraneous include files (most stuff was integrated in libcob.h)
  • fix warnings from C compiler when building GnuCOBOL
  • compiler configuration files are complete (include every option)

3.23.2   libcob:

  • FUNCTIONs: correctly compute RANDOM number [bugs:#72], don’t crash on large-scale numbers with INTEGER and MOD, don’t loose precision with MOD and REM [bugs:#37]
  • ACCEPT DAY OF WEEK fixed
  • new system routine C$GETPID
  • fix INSPECT converting for SPACE[S] / ZERO[ES] ...
  • fixes for UNSTRING: delimited by all delimiter size > 1, see [bugs:#54]; UNSTRING INTO; UNSTRING with multiple variable length fields
  • ACCEPT SCREEN: Changed insert key default to off, added environment variable COB_INSERT_MODE, Y or y to get old behaviour (insert default becomes on)
  • ACCEPT: fix for PDCurses and numpad in general; new return values Tab = 2007, Back tab = 2008; end key positions to end of data (was end of field), backspace key moves remainder left (inserts space at end or 0 for numerics)
  • fix for PDCurses with COLOR_PAIRS
  • fixing results for SUBTRACT int FROM PIC S9(n)V9(m) COMP-3, ADD 1 TO PIC S9(n)V9(m) VALUE -0.1, ADD with binary-truncate:no (for example with -std=ibm or std=mf)
  • fileio: lineseq_write adds ‘n’ in some cases (compatibility to MF) - be aware that this changes current behaviour (when WRITE AFTER/BEFORE are mixed)
  • fileio: Fix problem to rewrite INDEXED (VBISAM) record with alternate key
  • fileio: Prevent runtime crash when ASSIGN is missing in SELECT FILE

3.23.3   cobc:

  • new options –info (output of most important configuration/environment details); –list-system (displaying all registered system routines), -A and -Q (add options to C compile / link phase)
  • Warn if -Debug is used (because likely -debug was intended)
  • support for spaces in path names passed to cobc
  • enable linking of already assembled modules for different UNIXes
  • FREE: Remove of exception for NULL address (as this is explicit allowed)
  • fix incorrect counting of number of digits for “$”, “+”, and “-” [bugs:#39]
  • Lexer was missing comment lines in FREE format, i.e. trying to process “* COPY 12345.” and look for “12345” file as a copybook :-)
  • Added check for maximum size of group items
  • new compiler configuration default-organization: set to either record-sequential (default=old behaviour) or line-sequential
  • better warning/error messages

3.24   What is runtime.cfg?

New in the reportwriter branch, runtime.cfg is an assistive file the allows control over the run time environment for GnuCOBOL.

Placed in the same directory as the configuration files, runtime.cfg supports a small domain specific language, for setting and resetting various environment variables that influence a lot of GnuCOBOL features.

You can also include other configuration files, specific for the job at hand.

Valid keywords include:

  • setenv
  • unsetenv
  • include
  • includeif
  • reset

The default runtime.cfg entry includes documentation on how it all works.

# GnuCOBOL runtime configuration
#
# Copyright (C) 2015, 2016 Free Software Foundation, Inc.
# Written by Simon Sobisch, Ron Norman
#
# This file is part of the GnuCOBOL runtime.
#
# The GnuCOBOL runtime is free software: you can redistribute it
# and/or modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# GnuCOBOL is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with GnuCOBOL.  If not, see <http://www.gnu.org/licenses/>.


#
## General instructions
#

# The initial runtime.cfg file is found in the  $COB_CONFIG_DIR/config
# (  COB_CONFIG_DIR  defaults to  installdir/gnucobol  ).
# The environment variable  COB_RUNTIME_CONFIG  may define a different runtime
# configuration file to read.

# If settings are included in the runtime environment file multiple times
# then the last setting value is used, no warning occurs.

# Settings via environment variables always take precedence over settings
# that are given in runtime configuration files. And the environment is
# checked after completing processing of the runtime configuration file(s)

# All values set to string variables or environment variables are checked
# for  ${envvar}  and replacement is done at the time of the setting.

# Any environment variable may be set with the directive  setenv  .
# Example:  setenv COB_LIBARAY_PATH ${LD_LIBRARY_PATH}

# Any environment variable may be unset with the directive  unsetenv
# (one var per line).
# Example:  unsetenv COB_LIBRARY_PATH

# Runtime configuration files can include other files with the directive
# include.
# Example:  include my-runtime-configuration-file

# To include another configuration file only if it is present use the directive
# includeif.
# You can also use  ${envvar}  inside this.
# Example:  includeif ${HOME}/mygc.cfg

# If you want to reset a parameter to its default value use:
#    reset parametername

# Most runtime variables have boolean values, some are switches, some have
# string values, integer values and some are size values.
# The boolean values will be evaluated as following:
#   to true:          1, Y, ON, YES, TRUE  (no matter of case)
#   to false:         0, N, OFF
# A 'size' value is an integer optionally followed by K, M, or G for kilo, mega
# or giga.

# For convenience a parameter in the runtime.cfg file may be defined by using
# either the environment variable name or the parameter name.
# In most cases the environment variable name is the parameter name (in upper
# case) with the prefix  COB_  .

#
## General environment
#

# Environment name:  COB_DISABLE_WARNINGS
#   Parameter name:  disable_warnings
#          Purpose:  turn off runtime warning messages
#             Type:  boolean
#          Default:  false
#          Example:  DISABLE_WARNINGS  TRUE

# Environment name:  COB_ENV_MANGLE
#   Parameter name:  env_mangle
#          Purpose:  names checked in the environment would get non alphanumeric
#                    change to '_'
#             Type:  boolean
#          Default:  false
#          Example:  ENV_MANGLE  TRUE

# Environment name:  COB_SET_TRACE
#   Parameter name:  set_trace
#          Purpose:  to enable to COBOL trace feature
#             Type:  boolean
#          Default:  false
#          Example:  SET_TRACE  TRUE

# Environment name:  COB_TRACE_FILE
#   Parameter name:  trace_file
#          Purpose:  to define where COBOL trace output should go
#             Type:  string
#          Default:  stderr
#          Example:  TRACE_FILE  ${HOME}/mytrace.log

#
## Call environment
#

# Environment name:  COB_LIBRARY_PATH
#   Parameter name:  library_path
#          Purpose:  paths for dynamically-loadable modules
#             Type:  string
#             Note:  the default paths .:/installpath/extras are always
#                    added to the given paths
#          Example:  LIBRARY_PATH    /opt/myapp/test:/opt/myapp/production

# Environment name:  COB_PRE_LOAD
#   Parameter name:  pre_load
#          Purpose:  modules that are loaded during startup, can be used
#                    to CALL COBOL programs or C functions that are part
#                    of a module library
#             Type:  string
#             Note:  the modules listed should NOT include extensions, the
#                    runtime will use the right ones on the various platforms,
#                    COB_LIBRARY_PATH is used to locate the modules
#          Example:  PRE_LOAD      COBOL_function_library:external_c_library

# Environment name:  COB_LOAD_CASE
#   Parameter name:  load_case
#          Purpose:  resolve ALL called program names to UPPER or LOWER case
#             Type:  Only use  UPPER  or  LOWER
#          Default:  if not set program names in CALL are case sensitive
#          Example:  LOAD_CASE  UPPER

# Environment name:  COB_PHYSICAL_CANCEL
#   Parameter name:  physical_cancel
#          Purpose:  physically unload a dynamically-loadable module on CANCEL,
#                    this frees some RAM and allows the change of modules during
#                    run-time but needs more time to resolve CALLs (both to
#                    active and not-active programs)
#            Alias:  default_cancel_mode, LOGICAL_CANCELS (0 = yes)
#             Type:  boolean (evaluated for true only)
#          Default:  false
#          Example:  PHYSICAL_CANCEL  TRUE

#
## File I/O
#

# Environment name:  COB_VARSEQ_FORMAT
#   Parameter name:  varseq_format
#          Purpose:  declare format used for variable length sequential files
#                    - different types and lengths precede each record
#                    - 'length' is the data length & does not include the prefix
#             Type:  0   means 2 byte record length (big-endian) + 2 NULs
#                    1   means 4 byte record length (big-endian)
#                    2   means 4 byte record length (local machine int)
#                    3   means 2 byte record length (big-endian)
#          Default:  0
#          Example:  VARSEQ_FORMAT 1

# Environment name:  COB_FILE_PATH
#   Parameter name:  file_path
#          Purpose:  define default location where data files are stored
#             Type:  file path directory
#          Default:  .  (current directory)
#          Example:  FILE_PATH ${HOME}/mydata

# Environment name:  COB_LS_FIXED
#   Parameter name:  ls_fixed
#          Purpose:  Defines if LINE SEQUENTIAL files should be fixed length
#                    (or variable, by removing trailing spaces)
#            Alias:  STRIP_TRAILING_SPACES  (0 = yes)
#             Type:  boolean
#          Default:  false
#          Example:  LS_FIXED TRUE

# Environment name:  COB_LS_NULLS
#   Parameter name:  ls_nulls
#          Purpose:  Defines for LINE SEQUENTIAL files what to do with data
#                    which is not DISPLAY type.  This could happen if a LINE
#                    SEQUENTIAL record has COMP data fields in it.
#             Type:  boolean
#          Default:  false
#             Note:  The TRUE setting will handle files that contain COMP data
#                    in a similar manner to the method used by Micro Focus COBOL
#          Example:  LS_NULL = TRUE

# Environment name:  COB_SYNC
#   Parameter name:  sync
#          Purpose:  Should the file be synced to disk after each write/update
#             Type:  boolean
#          Default:  false
#          Example:  SYNC: TRUE

# Environment name:  COB_SORT_MEMORY
#   Parameter name:  sort_memory
#          Purpose:  Defines how much RAM to assign for sorting data
#             Type:  size  but must be more than 1M
#          Default:  128M
#          Example:  SORT_MEMORY 64M

# Environment name:  COB_SORT_CHUNK
#   Parameter name:  sort_chunk
#          Purpose:  Defines how much RAM to assign for sorting data in chunks
#             Type:  size  but must be within 128K and 16M
#          Default:  256K
#          Example:  SORT_CHUNK 1M

#
## Screen I/O
#

# Environment name:  COB_BELL
#   Parameter name:  bell
#          Purpose:  Defines how a request for the screen to beep is handled
#             Type:  FLASH, SPEAKER, FALSE, BEEP
#          Default:  BEEP
#          Example:  BELL SPEAKER

# Environment name:  COB_REDIRECT_DISPLAY
#   Parameter name:  redirect_display
#          Purpose:  Defines if DISPLAY output should be sent to 'stderr'
#             Type:  boolean
#          Default:  false
#          Example:  redirect_display Yes

# Environment name:  COB_SCREEN_ESC
#   Parameter name:  screen_esc
#          Purpose:  Enable handling of ESC key during ACCEPT
#             Type:  boolean
#          Default:  false
#             Note:  is only evaluated if COB_SCREEN_EXCEPTIONS is active
#          Example:  screen_esc Yes

# Environment name:  COB_SCREEN_EXCEPTIONS
#   Parameter name:  screen_exceptions
#          Purpose:  enable exceptions for function keys during ACCEPT
#             Type:  boolean
#          Default:  false
#          Example:  screen_exceptions Yes

# Environment name:  COB_TIMEOUT_SCALE
#   Parameter name:  timeout_scale
#          Purpose:  specify translation in milliseconds for ACCEPT clauses
#                    BEFORE TIME value / AFTER TIMEOUT
#             Type:  integer
#                    0 means 1000 (Micro Focus COBOL compatible), 1 means 100
#                    (ACUCOBOL compatible), 2 means 10, 3 means 1
#          Default:  0
#          Example:  timeout_scale 3

# Environment name:  COB_INSERT_MODE
#   Parameter name:  insert_mode
#          Purpose:  specify default insert mode for ACCEPT; 0=off, 1=on
#             Type:  boolean
#          Default:  false
#          Example:  insert_mode Y

# Environment name:  COB_LEGACY
#   Parameter name:  legacy
#          Purpose:  keep behaviour of former runtime versions, currently only
#                    for setting screen attributes for non input fields
#             Type:  boolean
#          Default:  not set
#          Example:  legacy true

# Environment name:  COB_EXIT_WAIT
#   Parameter name:  exit_wait
#          Purpose:  to wait on main program exit if an extended screenio
#                    DISPLAY was issued without an ACCEPT following
#             Type:  boolean
#          Default:  true
#          Example:  COB_EXIT_WAIT off

# Environment name:  COB_EXIT_MSG
#   Parameter name:  exit_msg
#          Purpose:  string to display if COB_EXIT_WAIT is processed, set to ''
#                    if no actual display but an ACCEPT should be done
#             Type:  string
#          Default:  'end of program, please press a key to exit' (localized)
#          Example:  COB_EXIT_MSG ''

# Note: If you want to slightly speed up a program's startup time, remove all
#       of the comments from the actual real file that is processed

And the delta between current GnuCOBOL 2.0 and ReportWriter as of January 2017:

105a106,114
> # Environment name:  COB_CURRENT_DATE
> #   Parameter name:  current_date
> #          Purpose:  specify an alternate Date/Time to be returned to ACCEPT
clauses
> #                    This is used for testing purposes
> #            Alias:  COB_DATE
> #             Type:  Numeric string in format YYYYDDMMHH24MISS
> #          Default:  The operating system date is use
> #          Example:  COB_CURRENT_DATE "2016/03/16 16:40:52"
>
159a169,171
> #                    b32 means 4 byte record length (big-endian)
> #                    l32 means 4 byte record length (little-endian)
> #                    mf  means Micro Focus default
162a175,201
> # Environment name:  COB_VARREL_FORMAT
> #   Parameter name:  varrel_format
> #          Purpose:  declare format to be used for variable length relative
> #                    files (different types and lengths preceding each
record)
> #             Type:  0   means local machine 'size_t'
> #                    b32 means 4 byte record length (big-endian)
> #                    l32 means 4 byte record length (little-endian)
> #                    b64 means 8 byte record length (big-endian)
> #                    l64 means 8 byte record length (little-endian)
> #                    mf  means Micro Focus default
> #                    gc  means GnuCOBOL default (local 'size_t')
> #          Default:  0
> #          Example:  VARREL_FORMAT B32
>
> # Environment name:  COB_FIXREL_FORMAT
> #   Parameter name:  fixrel_format
> #          Purpose:  declare format to be used for fixed length relative
> #                    files (different types and lengths preceding each
record)
> #             Type:  b32 means 4 byte record length (big-endian)
> #                    l32 means 4 byte record length (little-endian)
> #                    b64 means 8 byte record length (big-endian)
> #                    l64 means 8 byte record length (little-endian)
> #                    mf  means Micro Focus default
> #                    gc  means GnuCOBOL default (local 'size_t')
> #          Default:  gc  fixed size with no record length prefix
> #          Example:  FIXREL_FORMAT B32
>
188c227,247
< #          Example:  LS_NULL = TRUE
---
> #          Example:  LS_NULLS = TRUE
>
> # Environment name:  COB_LS_VALIDATE
> #   Parameter name:  ls_validate
> #          Purpose:  Defines for LINE SEQUENTIAL files that the data should
be
> #                    validated. If any record has non-DISPLAY characters
then
> #                    an error status of 30 is returned
> #             Type:  boolean
> #          Default:  true
> #             Note:  The TRUE setting does data validation
> #                    The FALSE setting lets non-DISPLAY characters be
written
> #                    If LS_NULLS is set, then LS_VALIDATE is not checked
> #          Example:  LS_VALIDATE = FALSE
>
> # Environment name:  COB_MF_FILES
> #   Parameter name:  mf_files
> #          Purpose:  Declares that all files in the program should follow
> #                    Micro Focus format
> #             Type:  boolean
> #          Default:  false
> #          Example:  MF_FILES = TRUE
253,259d311
<
< # Environment name:  COB_INSERT_MODE
< #   Parameter name:  insert_mode
< #          Purpose:  specify default insert mode for ACCEPT; 0=off, 1=on
< #             Type:  boolean
< #          Default:  false
< #          Example:  insert_mode Y

3.25   How do I get the length of a LINE SEQUENTIAL read?

When using ACCESS MODE IS LINE SEQUENTIAL the number of bytes read for the current record will be set in an identifier by using an FD VARYING DEPENDING ON clause.

For example,

FD infile
    RECORD IS VARYING IN SIZE FROM 1 TO 65535 CHARACTERS
    DEPENDING ON infile-record-length.
01 infile-record.
   05 infile-data      PIC X OCCURS 65535 TIMES
                       DEPENDING ON infile-record-length.

That can be shortened to

FD infile RECORD VARYING DEPENDING ON infile-record-length.

Implicitly set on READ, and controls lengths of WRITE when explicitly set before a WRITE or REWRITE operation.

This FD VARYING clause can also be specified with normal SEQUENTIAL (BINARY SEQUENTIAL) access mode, but that mode is more generally used with already known values and fixed length records.

The identifier can be pretty much any NUMERIC type, but is limited to PIC 9(9) in size, just shy of one billion for record lengths.

3.27   How do I measure GnuCOBOL performance?

With great care and attention to detail.

Measuring performance is a rather tricky business. There are many pitfalls in gleaning accurate performance information. But for day to day ballpark estimates there are a variety of tools to sate curiousity, from simple to outright complex.

3.27.1   Benchmarks

There are not a lot of publicly available COBOL benchmark programs. This is partly due to the historically closed nature of big business COBOL and partly due to the lack of a free COBOL compiler of GnuCOBOL quality during the long history of COBOL development. That status should change now that GnuCOBOL is more widely available.

One benchmark used with GnuCOBOL is the Telco billing program, listed in the FAQ at What about GnuCOBOL and benchmarks? from code written by Bill Klein and modified by Roger While. More benchmarking suites will be added to this FAQ as they become known and available.

3.27.2   GNU/Linux

For most of the examples listed below, anagrams.cob was used. Sources for this word sorting application can be found on Rosetta Code at:

http://rosettacode.org/wiki/Anagrams#COBOL

There are some very easy ways to get a rough measure of GnuCOBOL program performance when running GNU/Linux.

The time command is one of the first level entries.

prompt$ time cobc -x anagrams.cob

real    0m0.115s
user    0m0.088s
sys     0m0.020s

Compiling the code took just over 1/10th of a second from a human perspective with about 2/100ths of a second of measurable time in the Linux kernel, and another 8/100ths of a second in GNU userland. CPU values, I/O and especially I/O waits can influence the real value considerably.

prompt$ time ./anagrams
2016-04-28T05:16:17.999194355, 000018977 seconds past midnight
25104 words, most anagrams: 05
abel      [abel, able, bale, bela, elba]
acert     [caret, carte, cater, crate, trace]
aegln     [angel, angle, galen, glean, lange]
aeglr     [alger, glare, lager, large, regal]
aeln      [elan, lane, lean, lena, neal]
eilv      [evil, levi, live, veil, vile]
2016-04-28T05:16:18.034565633, 000018978 seconds past midnight

real    0m0.042s
user    0m0.032s
sys     0m0.008s

These are very rough estimates, and very dependent on current system activity and a host of other factors. Rough estimates, also limited by available resolution of measurable time slices.

The timestamps displayed by GnuCOBOL started at 17.999 and ended at 18.034, so just over 3/10ths of a second for the run, including all the I/O to disk and screen. Which is pretty close to the 4/10ths reported by time for the real field. As shown, the code scanned for anagrams from a list of 25104 words, read in from a text file with one word per line.

The gprof command is another entry level tool. These profiling feature are added by passing the -pg option to the gcc compile step when building a GnuCOBOL executable (or object code).

prompt$ cobc -x -Q '-pg' anagrams.cob
prompt$ ./anagrams
2016-04-28T05:13:01.894518641, 000018781 seconds past midnight
25104 words, most anagrams: 05
abel      [abel, able, bale, bela, elba]
acert     [caret, carte, cater, crate, trace]
aegln     [angel, angle, galen, glean, lange]
aeglr     [alger, glare, lager, large, regal]
aeln      [elan, lane, lean, lena, neal]
eilv      [evil, levi, live, veil, vile]
2016-04-28T05:13:01.933875670, 000018781 seconds past midnight

prompt$ ls -larct
-rwxrwxr-x  1 username groupname  20024 Apr 28 05:05 anagrams
-rw-rw-r--  1 username groupname   2797 Apr 28 05:05 gmon.out

prompt$ gprof anagrams
Flat profile:

Each sample counts as 0.01 seconds.
 no time accumulated

  %   cumulative   self              self     total
 time   seconds   seconds    calls  Ts/call  Ts/call  name
  0.00      0.00     0.00        1     0.00     0.00  anagrams
  0.00      0.00     0.00        1     0.00     0.00  anagrams_

The gcc -pg compile and link option inserts code to allow for simple function call profiling. This data is captured to gmon.out during a run. Turns out the anagram sample ran too fast for gprof to pick out much data.

A second level tool is the Linux kernel perf tool. It goes much deeper in analysis.

perf creates a perf.data during recording and pumps out a wide variety of information during reporting. This is a kernel tool as of Linux 2.6.31 (released in 2009), and is still deemed a lightweight performance measurement tool advertised as “more than just counters”.

Recording a run:

prompt$ perf record ./anagrams
2016-04-28T05:23:07.574207248, 000019387 seconds past midnight
25104 words, most anagrams: 05
abel      [abel, able, bale, bela, elba]
acert     [caret, carte, cater, crate, trace]
aegln     [angel, angle, galen, glean, lange]
aeglr     [alger, glare, lager, large, regal]
aeln      [elan, lane, lean, lena, neal]
eilv      [evil, levi, live, veil, vile]
2016-04-28T05:23:07.610477929, 000019387 seconds past midnight
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.008 MB perf.data (176 samples) ]

And then reporting details from the generated perf.data:

prompt$ perf report --stdio | cat
Warning:
Kernel address maps (/proc/{kallsyms,modules}) were restricted.

# Total Lost Samples: 0
#
# Samples: 176  of event 'cycles'
# Event count (approx.): 127807808
#
# Overhead  Command   Shared Object     Symbol
# ........  ........  ................  ...................................
#
    33.08%  anagrams  libcob.so.4.0.0   [.] sort_compare
    14.03%  anagrams  libc-2.21.so      [.] msort_with_tmp.part.0
     7.27%  anagrams  libc-2.21.so      [.] _IO_getc
     6.57%  anagrams  libc-2.21.so      [.] __memcpy_sse2
     5.31%  anagrams  libc-2.21.so      [.] __GI___mempcpy
     4.79%  anagrams  anagrams          [.] anagrams_
     2.30%  anagrams  [unknown]         [k] 0xffffffffxxxxxxxx
     2.25%  anagrams  libcob.so.4.0.0   [.] cob_move
     1.99%  anagrams  libc-2.21.so      [.] __GI___qsort_r
     1.99%  anagrams  libc-2.21.so      [.] _int_free
     1.95%  anagrams  libc-2.21.so      [.] __memcmp_sse4_1
     1.32%  anagrams  libcob.so.4.0.0   [.] cob_decimal_get_field
     1.14%  anagrams  libc-2.21.so      [.] __libc_calloc
     1.13%  anagrams  libcob.so.4.0.0   [.] cob_read_next
     1.10%  anagrams  libc-2.21.so      [.] __memmove_ssse3
     0.66%  anagrams  [unknown]         [k] 0xffffffffxxxxxxxx
     0.66%  anagrams  [unknown]         [k] 0xffffffffxxxxxxxx
     0.66%  anagrams  [unknown]         [k] 0xffffffffxxxxxxxx
     0.66%  anagrams  libcob.so.4.0.0   [.] cob_set_exception
     0.66%  anagrams  libgmp.so.10.2.0  [.] __gmpn_add_n
     0.66%  anagrams  libcob.so.4.0.0   [.] _IO_getc@plt
     0.66%  anagrams  libcob.so.4.0.0   [.] __gmpz_set_ui@plt
     0.66%  anagrams  libgmp.so.10.2.0  [.] __gmpz_sizeinbase
     0.66%  anagrams  libcob.so.4.0.0   [.] cob_intr_formatted_current_date
     0.64%  anagrams  [unknown]         [k] 0xffffffffxxxxxxxx
     0.64%  anagrams  [unknown]         [k] 0xffffffffxxxxxxxx
     0.54%  anagrams  [unknown]         [k] 0xffffffffxxxxxxxx
     0.52%  anagrams  [unknown]         [k] 0xffffffffxxxxxxxx
     0.51%  anagrams  ld-2.21.so        [.] _dl_map_object
     0.50%  anagrams  libcob.so.4.0.0   [.] lineseq_read
     0.50%  anagrams  ld-2.21.so        [.] strcmp
     0.49%  anagrams  libcob.so.4.0.0   [.] cob_malloc
     0.49%  anagrams  [unknown]         [k] 0xffffffffxxxxxxxx
     0.48%  anagrams  [unknown]         [k] 0xffffffffxxxxxxxx
     0.48%  anagrams  [unknown]         [k] 0xffffffffxxxxxxxx
     0.45%  anagrams  libc-2.21.so      [.] __memset_sse2
     0.43%  anagrams  [unknown]         [k] 0xffffffffxxxxxxxx
     0.42%  anagrams  [unknown]         [k] 0xffffffffxxxxxxxx
     0.41%  anagrams  libc-2.21.so      [.] memchr
     0.27%  anagrams  [unknown]         [k] 0xffffffffxxxxxxxx
     0.05%  anagrams  [unknown]         [k] 0xffffffffxxxxxxxx
     0.01%  anagrams  [unknown]         [k] 0xffffffffxxxxxxxx

Showing where the anagram program spent most of its time. perf is a kernel tool, and normally needs root access to get at some of the details. Those details are not included in this GNU userspace run and perf gave a warning pointing that out.

3.27.3   Other measurement tools

There are a lot of performance measurment tools, but for anything beyond very rough estimates, there needs to be a fair investment in time and attention to detail as each sample is analysed.

For Microsoft Windows, a few searches of MSDN will lead to list of official performance analysis tools that are available to developers on that platform.

For Apple, looking at XCode tools such as Instruments will provide a good start at measuring performance of GnuCOBOL executables.

3.27.4   -debug performance implications

Adding -debug to a cobc command line has very negligible impact on run-time of GnuCOBOL programs. There are quite a few extra C code lines generated, mostly to track section, paragraph and source line number for exception reporting, and there are also boundary checks added and a few other safey measures, but overall they don’t add much burden to executables. These C source lines usually compile down to a few small tests or variable settings, and will have little overall impact on performance, except in the most extreme cases of number crunching applications.

The anagrams.cob timing measurments with and without -debug ended up within the margin of error for the values. There was a wider range of timing values between various runs, then was detected by adding -debug, or not.

The GnuCOBOL project recommends compiling programs with -debug, even for production installs. Unless there are mitigating circumstances, the extra protections and ability for GnuCOBOL to report exact line numbers during exceptions are well worth it, and the -debug option is recommended by the project contributors. It’s optional and needs to be explicitly requested, but even for production builds, this setting is a recommended practice.

3.28   Are there bugs in GnuCOBOL?

Yes, some.

Not to put GnuCOBOL in the wrong light. It’s a capable compiler, but it’s not perfect, considering the nearly infinite permutations allowed in COBOL software development. Complexities can sometimes lead to compilation problems. But, in terms of trust, if the compilation succeeds, odds are strongly in favour of the runtime code doing the right thing. GnuCOBOL bugs are most often triggered at compile time, and there are usually work arounds. If there are problems with generated code, the problem will usually be immediately evident on initial tests.

If the compilation succeeds, and initial tests succeed, you can place as much faith in GnuCOBOL as any other complex compiler. When more faith is required, the generated C source codes can be passed through a myriad of static analysis and validation programs that are available for free and for fee. Beyond that, the generated assembler listings can be examined, and beyond that, runtime debuggers are always available.

To increase peace of mind, valgrind is a very capable tool. With point releases, the core GnuCOBOL test suite passes without leak, both in compiler and compiled code, or it doesn’t ship.

Almost done with the reputation disclaimers and marketing speak, but two more things needs to be addressed, and this is not unique to GnuCOBOL.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

And now on to the realities of some known problems.

Of special note are the edge cases surrounding foreign function interfacing and BY VALUE parameter handling with CALL and PROCEDURE DIVISION USING. COBOL has a very specific, and rigid, view of data types, and it is sometimes tricky mapping that to non-COBOL programs with different features allowed in call frame setup.

CALL BY VALUE and PROCEDURE DIVISION USING BY VALUE need special care and attention.

When calling FUNCTION-ID numeric literals can cause problems, the data is currently passed to the function as a string form. PIC 9 ANY LENGTH in the LINKAGE SECTION may work, but the best work around is to use intermediate working storage and MOVE, as then GnuCOBOL will have explicit data types to work with. Numerical literals currently have no default type with GnuCOBOL User Defined Functions. This will be fixed, but for now, the intermediate working storage method works the best.

User Defined Functions cannot return POINTER data, but can return a record that has a POINTER as the first field.

01 user-pointer USAGE POINTER.

MOVE user-function(user-data) TO user-pointer

Will not properly compile. It’s a bug, and it will be fixed.

01 user-record.
   05 user-pointer USAGE POINTER.

MOVE user-function(user-data) to user-record

Will properly compile and execute. Functions are great for returning group items, so the above RETURNING block can add all sorts of other fields to the return values for user functions.

In terms of core COBOL, there are still a few bugs that need to be found and fixed, but not many. The NIST testsuite passes with flying colours, the internal integrity checks during compiler builds are extensive and growing.

3.29   How do C data types map to GnuCOBOL data definitions?

Very carefully. The C standard is somewhat ambiguous about data types, with a few specific exceptions.

For the most part, the C standard (and GnuCOBOL is best when used with C99 expectations), defines data types using at least qualifiers. A short is at least as large as a char, possibly larger. An int is at least as big as a short, and a long is at least at big as an int. And one of the few exceptions, by standard sizeof(char) is 1, by definition. That means a char is an 8 bit byte, but the signed/unsigned default is still implementation defined.

Sadly, by standard char, signed char, and unsigned char are three distinct types. Many people may assume unsigned, and that a C compiler will allow 0 thru 255, and not -128 through 127, but you need to look at the implementation details. This author is a gcc user, and GNU C implements char as signed char.

#include <stdio.h>

int
main(int argc, char** argv)
{
    char c;
    c = 127;
    printf("%d\n", c);
    c += 1;
    printf("%d\n", c);
    c += 1;
    printf("%d\n", c);
    return 0;
}

Which produces:

prompt$ gcc chars.c
prompt$ ./a.out
127
-128
-127

Yayy, C standard.

COBOL is not that ambiguous. A BINARY-CHAR is and 8 bit byte, defaulting to SIGNED unless otherwise specified with an UNSIGNED qualifier. By spec.

A BINARY-SHORT is 16 bits, again SIGNED unless otherwise specified.

A BINARY-LONG is 32 bits, SIGNED.

A BINARY-DOUBLE is 64 bits, SIGNED by default.

So, when coding to a C long, the native system may compile 16 bits, 32 bits, or 64 bits signed by default. Only char suffers from no specified signed or unsigned default. (In extreme cases you might even get an 8 bit long quantity, but by then you are likely programming embedded chips and probably know more about what you are doing than most developers). What this all means is that mapping from COBOL to C is a little bit hit or miss and hard to get completely cross platform results without building in a knowledge base of target systems (or writing a support tool that compiles native C and then modifies compiler directives to pass in COBOL preprocessor defines, or some such).

By and large we get away with

8 bit char, 16 bit short, 32 bit int, and 64 bit long. For robust software, that doesn’t really cut it, and for interfacing to C it becomes a bit of a shell game. One of the more notorious culprits is Microsoft C Win64. A pointer is 64 bits, a long int is 32 bits and a long long int is 64 bits. By that convention I guess a 128 bit integral value will be long long long long int, and the kids will really be up against it. 96 bits being a long long long int. Current standards are leaving the ambiguous definitions and adding more sane type names. C99 defines explicit uint8_t, uint_16, etcetera. The future may not be as bleak as long long long long int. But C99 also adds uint_fast8_t and int_least64_t style unfixed width types, so perhaps the games get to continue. Who wouldn’t want to use ..fast.., sounds fast.

GnuCOBOL has an extension BINARY-C-LONG, that compiles the right size for a C long, (by knowing what the target C compiler is and, well, just knowing, by rote built in knowledge base).

More fortunately, the floating point types are little more sane, COBOL FLOAT-SHORT is a C float and a FLOAT-LONG is a C double. Then again, COBOL isn’t really a friend of binary floating point, built instead for robust support of decimal arithmetic.

3.29.1   Structures

C usually pads structures for optimal CPU performance. An 8 bit field followed by a 32 bit field will usually leave 3 bytes of padding to align the 32 field on a mod 4 base address. COBOL is not defined that way, record groups are contiguous, normally. GnuCOBOL supports the SYNCHRONIZED data attribute clause, or SYNCH for short. The compiler will pad grouped fields that are marked as SYNCH to match the assumptions of the native C compiler.

4   Reserved Words

Index

4.1   What are the GnuCOBOL RESERVED words?

COBOL is a reserved word rich language. The GnuCOBOL compiler recognizes:

514 words in OC 1.1, 136 of which are marked not yet implemented. 378 functional reserved words, as of August 2008.

592 words listed in the reportwriter branch, 472 marked implemented as of January 2015.

4.1.1   ACCEPT

Makes data available from the keyboard or operating system to named data items. GnuCOBOL supports both standard and extended ACCEPT statements.

Most extended ACCEPT statements will require an advanced terminal screen initialization, which can obscure CONSOLE input and output. See Why don’t I see any output from my GnuCOBOL program? for some details on this issue.

_images/accept-statement.png

A short list of ACCEPT sources:

ACCEPT variable FROM CONSOLE.

ACCEPT variable FROM ENVIRONMENT "path".
ACCEPT variable FROM COMMAND-LINE.

ACCEPT variable FROM ARGUMENT-NUMBER
ACCEPT variable FROM ARGUMENT-VALUE

ACCEPT variable AT 0101.
ACCEPT screen-variable.

ACCEPT today FROM DATE.
ACCEPT today FROM DATE YYYYMMDD.
ACCEPT thetime FROM TIME.

ACCEPT theday FROM DAY.
ACCEPT theday FROM DAY YYYYDDD.

ACCEPT weekday FROM DAY-OF-WEEK.

ACCEPT thekey FROM ESCAPE KEY.

ACCEPT username FROM USER NAME.

ACCEPT exception-stat FROM EXCEPTION STATUS.

ACCEPT some-data FROM device-name.

Extended attributes (requires WITH keyword):

_images/extended-accept.png

Please note: ACCEPT datafield WITH extended-attributes will cause initialization of the extended IO Terminal User Interface system. That means all further IO to the display is subject to the rules of SMCUP and RMCUP.

4.1.1.1   ACCEPT OMITTED

ACCEPT OMITTED.   *> Waits for a keystroke that includes terminator.

This form of accept will wait for a keyboard event that terminates input; function keys, or Enter/Return, among others. CRT STATUS (COB-CRT-STATUS if not explicitly defined) is set with the keycode, listed in copy/screenio.cpy. ACCEPT OMITTED also handles a few other keycode terminations not normally used to complete an extended accept:

  • COB-SCR-INSERT
  • COB-SCR-DELETE
  • COB-SCR-BACKSPACE
  • COB-SCR-KEY-HOME
  • COB-SCR-KEY-END

You can used extended attributes with OMITTED, handy for setting timeouts or positioning.

4.1.1.2   ACCEPT ON EXCEPTION

Empty input from the keyboard (Ctrl-D in a GNU/Linux terminal, for instance) can be detected with ON EXCEPTION conditional statements.

ACCEPT datafield
    ON EXCEPTION
        display "datafield got EOF, not changed"
END-ACCEPT

Otherwise, on EOF and console ACCEPT, COBOL will continue, with the accept destination field unchanged.

See AT, WITH.

4.1.1.3   EXCEPTION-STATUS

ACCEPT exception-pic9-4 FROM EXCEPTION-STATUS

comes in handy when dealing with

COMPUTE delicate-value ROUNDED MODE IS PROHIBITED
          = interest-by-loop - interest-by-new-formula
    ON SIZE ERROR
        DISPLAY
            "Rats.  Call the boss, the new formula fell over"
            UPON SYSERR
END-COMPUTE

ACCEPT unexpected-rounding  FROM EXCEPTION-STATUS
IF unexpected-rounding NOT EQUAL "0000" THEN
    DISPLAY
        "Rats. Unexpected rounding. Code " unexpected-rounding
        UPON SYSERR
END-IF

4.1.2   ACCESS

Defines a file’s access mode. One of DYNAMIC, RANDOM, SEQUENTIAL, or LINE SEQUENTIAL.

LINE SEQUENTIAL is not standard in the specification, but common with many COBOL implementations, and very handy when processing text files.

See How do I get the length of a LINE SEQUENTIAL read? for some details.

An example setting up RANDOM access by key:

SELECT filename
    ASSIGN TO "filename.dat"
    ACCESS MODE IS RANDOM
    RELATIVE KEY IS keyfield.

4.1.3   ACTIVE-CLASS

Not yet implemented. Object COBOL feature.

4.1.4   ADD

Sums two or more numerics, with an eye toward financial precision and error detection. Can also be used with CORRESPONDING to add entire groups of matching fieldnames together.

ADD 1 TO cobol

ADD 1 TO cobol GIVING GnuCOBOL

ADD
    a b c d f g h i j k l m n o p q r s t u v w x y z
    GIVING total-of
    ON SIZE ERROR
        PERFORM log-problem
    NOT ON SIZE ERROR
        PERFORM graph-result
END-ADD
_images/add-statement.png

With ROUNDED options:

_images/rounded-phrase.png

4.1.4.1   TO and GIVING

Bill Woodger points out that using TO and GIVING together can lead to some confusion. With

ADD 1 TO GnuCOBOL

GnuCOBOL is a receiving field and is modified, adding the literal to current contents.

ADD 1 TO GnuCOBOL GIVING NewCOBOL

GnuCOBOL is a sending field and is not modified. Even though it reads well as English, some programmers may assume that the TO field is being changed, when it is not. A more concise expression might be:

ADD 1 GnuCOBOL GIVING NewCOBOL

Both are valid, both are to specificiation, but you might make a maintainer’s life easier if you don’t use both TO and GIVING in the same statement.

4.1.4.2   ADD CORRESPONDING

*> Modified: 2016-05-18/19:10-0400
 COPY sample-template REPLACING
 ==:DATABOOK:== BY
 ==

 01 data-group.
    05 top-group.
       10 field-a        pic 9(5) value 1.
       10 field-b        pic 9(5) value 2.
       10 inner-group.
          15 field-c     pic 9(5) value 3.
       10 field-d        pic 9(5) value 4.
    05 field-e           pic 9(5) value 5.
    05 field-f           pic x(3) value "006".
    05 field-g           pic x(3) value "abc".

 01 other-group.
    05 top-group.
       10 field-c        pic 9(5).
       10 field-b        usage binary-long.
       10 field-a        usage float-short.
    05 field-d           pic s9(5).
    05 field-z           pic s9(5).
    05 field-f           pic 9(3).
    05 field-g           pic 9(3).

 ==
 ==:CODEBOOK:== BY
 ==

 add corresponding data-group to other-group
 display "field-a: " field-a of other-group
 display "field-b: " field-b of other-group
 display "field-c: " field-c of other-group
 display "field-d: " field-d of other-group
 display "field-z: " field-z of other-group
 display "field-f: " field-f of other-group
 display "field-g: " field-g of other-group

 ==
 .

field-a, field-b match. field-c, field-d do not (due to grouping level). fielf-g is an erroneous outcome. There is a bug. The ADD CORRESPONDING, which is treated partly as a field by field add, but also partly like a raw group data add. (Hint: it has to do with low-nibbles in the ASCII encoding system, “abc” is equivalent to x”616263”) but the non-numeric data should not be included in the field match.

prompt$ cobc -xj add-sample.cob
field-a: 1
field-b: +0000000002
field-c: 00000
field-d: +00000
field-z: +00000
field-f: 006
field-g: 123

See Sample shortforms for the sample-template listing.

4.1.5   ADDRESS

Allows program access to memory address reference and, under controlled conditions, assignment.

SET pointer-variable TO ADDRESS OF linkage-store

SET ADDRESS OF based-var TO pointer-from-c

SET prog-pointer TO ADDRESS OF PROGRAM "entry-point"

CALL "program" RETURNING ADDRESS OF linkage-or-based-var

For an example, using a POINTER along with a BASED POINTER, it is possible to traverse a C, null terminated, string without a buffer allocation, see Can GnuCOBOL display the process environment space?

4.1.6   ADVANCING

Programmer control of newline output and paging.

DISPLAY "Legend: " WITH NO ADVANCING
WRITE printrecord AFTER ADVANCING PAGE
WRITE printrecord BEFORE ADVANCING 3 LINES

SELECT printseq
    ASSIGN TO LINE ADVANCING FILE "printer-file"

4.1.7   AFTER

  • An optional INSPECT clause
  • An optional WRITE clause
  • When specifying out-of-band, declarative procedures
  • Nested PERFORM clause
  • influence when loop conditional testing occurs

A sample with nested AFTER and TEST AFTER

PERFORM
    WITH TEST AFTER
    VARYING variable FROM 1 BY 1
    UNTIL variable > 10
        AFTER inner FROM 1 BY 1
        UNTIL inner > 4
             DISPLAY variable ", " inner
END-PERFORM.

Will display 55 lines of output. 1 to 11 and 1 to 5. Removing the WITH TEST AFTER clause would cause 40 lines of output. 1 to 10 and 1 to 4.

Same nested loop without the TEST AFTER control flow modifier

PERFORM
    VARYING variable FROM 1 BY 1
    UNTIL variable > 10
        AFTER inner FROM 1 BY 1
        UNTIL inner > 4
            DISPLAY variable ", " inner
END-PERFORM

Which gives 40 output lines. The WITH TEST AFTER in the original listing applies to both the outer and the nested loops.

With INSPECT:

INSPECT variable REPLACING "/" BY ":" AFTER INITIAL SPACE

With WRITE, usually when generating output destined for printing:

WRITE title-record AFTER ADVANCING PAGE
WRITE record-name AFTER ADVANCING 2 LINES

Declartives:

procedure division.
declaratives.
handlers section.
use after standard error procedure on input.
    display "Error during read" upon syserr
    exit
.
end declaratives.

4.1.8   ALIGNED

Not yet implemented feature that will influence the internal alignment of not yet implemented USAGE BIT fields.

4.1.9   ALL

A multipurpose reserved in context word.

INSPECT variable REPLACING ALL "123" WITH "456".

MOVE ALL QUOTES TO var.

Unfortunately, GnuCOBOL does yet support the ALL subscripting keyword for Intrinsic Functions, so

COMPUTE biggest = FUNCTION MAX(table-field(ALL))

will not work in GnuCOBOL, yet.

4.1.10   ALLOCATE

Allocates working storage for a BASED element, or allocate a given size of heap storage.

_images/allocate-statement.png
01 pointer-var         usage POINTER.
01 character-field     pic x(80) BASED value "Sample".

ALLOCATE 1024 characters returning pointer-var
ALLOCATE character-field
ALLOCATE character-field INITIALIZED RETURNING pointer-var

See FREE.

4.1.11   ALPHABET

* Set up for a mixed case SORT COLLATING SEQUENCE IS
 ENVIRONMENT DIVISION.
 CONFIGURATION SECTION.
 SPECIAL-NAMES.
     ALPHABET mixed IS "AaBbCcDdEeFfGgHhIiJjKkLlMm" &
                       "NnOoPpQqRrSsTtUuVvWwXxYyZz".

 DATA DIVISION.
 01 accounts.
    05 tables-data OCCURS 1 TO 1000 TIMES
           DEPENDING ON total-accounts
           ASCENDING KEY account-key
           INDEXED BY account-index.


 SORT table-data
     ON DESCENDING KEY account-key
     COLLATING SEQUENCE IS mixed.

4.1.12   ALPHABETIC

One of the GnuCOBOL data class (category) tests.

IF variable IS ALPHABETIC
    DISPLAY "alphabetic"
END-IF

ALPHABETIC is defined as a data item that uses only A in the PICTURE clause. Finding examples of ALPHABETIC data use is difficult, which means this type is rarely used, favouring ALPHANUMERIC instead.

When tested, only data that are upper case A to Z and lower case a to z will return true, all others, including any digits 0 to 9 will return false.

4.1.13   ALPHABETIC-LOWER

One of the GnuCOBOL data class (category) tests.

IF variable IS ALPHABETIC-LOWER
    DISPLAY "alphabetic-lower"
END-IF

4.1.14   ALPHABETIC-UPPER

One of the GnuCOBOL data class (category) tests.

DISPLAY variable "alphabetic-upper " WITH NO ADVANCING
IF variable IS ALPHABETIC-UPPER
    DISPLAY "true A-Z, and nothing but A to Z"
ELSE
    DISPLAY "false A-Z, something else in here"
END-IF

4.1.15   ALPHANUMERIC

A COBOL data category, probably the most common. PIC X. ALPHANUMERIC can be used with INITIALIZE, along with other category names.

INITIALIZE data-record REPLACING ALPHANUMERIC BY literal-value

4.1.16   ALPHANUMERIC-EDITED

A trickier to describe COBOL data category. See PICTURE for details on the editing characters available with GnuCOBOL.

INITIALIZE data-record
    REPLACING ALPHANUMERIC-EDITED BY identifier-1

4.1.17   ALSO

A powerful, multiple conditional expression feature of EVALUATE.

EVALUATE variable ALSO second-var ALSO statuate-42
    WHEN "A"      ALSO 1 THRU 5   ALSO ANY         PERFORM first-case
    WHEN "A"      ALSO 6          ALSO 1 THRU 8    PERFORM second-case
    WHEN "A"      ALSO 6          ALSO 9           PERFORM special-case
    WHEN "A"      ALSO 7 THRU 9   ALSO ANY         PERFORM third-case
    WHEN OTHER                                     PERFORM invalid-case
END-EVALUATE

4.1.18   ALTER

Obsolete, but still supported verb that modifies the jump target for GO TO statements.

_images/alter-statement.png

Use with care. Unless you are writing a state machine engine, maybe. ALTER should rarely be used in COBOL applications without due reason.

GnuCOBOL 2.0 may support this verb, to increase support for legacy code, but NOT as homage to a good idea. To be honest, I might like to see a GnuCOBOL Flying Spaghetti Monster (that works), simply for the eye rolling of righteous indignation, and perhaps the schadenfreude.

Reality is, 2.0 does support ALTER. NIST Test Suite runs now pass over 9,700 tests, up from just under 9,100 with 1.1.

A contrived example of ALTER label PROCEEDING TO. Two samples of the output follow, one without, and one with COB_SET_TRACE enabled.

 identification division.
 program-id. altering.
 author. Brian Tiffin.
 date-written. 2015-10-28/06:36-0400.
 remarks. Demonstrate ALTER.

 procedure division.
 main section.

*> And now for some altering.
 contrived.
 ALTER story TO PROCEED TO beginning
 GO TO story
 .

*> Jump to a part of the story
 story.
 GO.
 .

*> the first part
 beginning.
 ALTER story TO PROCEED to middle
 DISPLAY "This is the start of a changing story"
 GO TO story
 .

*> the middle bit
 middle.
 ALTER story TO PROCEED to ending
 DISPLAY "The story progresses"
 GO TO story
 .

*> the climatic finish
 ending.
 DISPLAY "The story ends, happily ever after"
 .

*> fall through to the exit
 exit program.

Giving:

prompt$ cobc -xj -debug altering.cob
This is the start of a changing story
The story progresses
The story ends, happily ever after

prompt$ COB_SET_TRACE=Y ./altering
Source:     'altering.cob'
Program-Id: altering         Entry:     altering               Line: 8
Program-Id: altering         Section:   main                   Line: 8
Program-Id: altering         Paragraph: contrived              Line: 11
Program-Id: altering         Statement: ALTER                  Line: 12
Program-Id: altering         Statement: GO TO                  Line: 13
Program-Id: altering         Paragraph: story                  Line: 17
Program-Id: altering         Paragraph: beginning              Line: 22
Program-Id: altering         Statement: ALTER                  Line: 23
Program-Id: altering         Statement: DISPLAY                Line: 24
This is the start of a changing story
Program-Id: altering         Statement: GO TO                  Line: 25
Program-Id: altering         Paragraph: story                  Line: 17
Program-Id: altering         Paragraph: middle                 Line: 29
Program-Id: altering         Statement: ALTER                  Line: 30
Program-Id: altering         Statement: DISPLAY                Line: 31
The story progresses
Program-Id: altering         Statement: GO TO                  Line: 32
Program-Id: altering         Paragraph: story                  Line: 17
Program-Id: altering         Paragraph: ending                 Line: 36
Program-Id: altering         Statement: DISPLAY                Line: 37
The story ends, happily ever after
Program-Id: altering         Statement: EXIT PROGRAM           Line: 41
Program-Id: altering         Exit:      altering
prompt$

Again, except for passing more tests within the NIST COBOL85 stress test, use of ALTER may be frowned upon by others. But, under some circumstances, may be a justified path to modify a complex system faced with new legal requirements and only a few minutes to spare before a monthly report needs to be filed. Know it is there, and use with care and understanding.

Another issue to consider is self modifying code runs counter to many modern instruction caching and predictive branch techniques, and there is always a possibilty that a new value for a jump may not be properly synched between active cache and addressable memory.

A more realistic and pragmatic view from Bill Woodger:

By the time I started, an ALTERed GO TO was already anathema. Not only
where I worked, but people who'd come from other sites, and the computer
press.

In itself, it is not a bad thing, but it seems in most of its uses, it was
done badly. It was used to (attempt to) implement business-logic, in large
programs.

Large programs of the time already suffered from being largely
"fall-through" (lack of use of PERFORM). Ordinary GO TO and DEPENDING ON
were already used, often badly or tortuously (a GO TO solely to jump over
a few conditions, a DEPENDING ON relating to a transaction-type, flying
off to one of 70 paragraphs, almost all of which (but you could be sure,
not all) would GO TO the top of that processing again to read another
record.

You make that worse by using ALTER just because you can.

The common complaint with ALTER is  that it obscures the flow of the
program for analysis, and it obscures you when something takes a dive at
2am and you're looking at a core-dump and wondering what was the current
value of the ALTERered GOs.

The latter argument is a bit fake, because the generated pseudo-assembler
shows you where the current barch-to address is stored. It may be valid for
other compilers.

The classic actual presumed OK use of ALTER is for performance. A branch
is faster than any test-and-branch. The more tests you can avoid (since
they can no longer ever be true, different from the "jump over" GO TO) the
faster the program runs.

An implementation of "PERFORM" using ALTERed GO TOs would be faster than an
actual PEFORM (in IBM Mainframe COBOLs) because you don't have to cater for
fall-through/GO TO/PERFORM potentially affecting the same label.

(As an aside I implemented "PERFORM" with GOTO &name in IBM's VS/Script
GML, because it didn't have anything for "perform" and having it made it
about 90% simpler to write a particular system specification).

I don't know what the original intent of ALTER was.

ALTER can be used safely. But it can't be used safely because no-one
believes it can be used safely. Reality vs Myth, score one for Myth.

And then more from Bill:

If COBOL didn't have PERFORM...
    ALTER PERFORM-IT TO PROCEED TO A
    ALTER RETURN-TO TO PROCEED TO NEXT-PARA
    GO TO PERFORM-IT
    .
NEXT-PARA.
    ALTER PERFORM-IT TO PROCEED TO B
    ALTER RETURN-TO TO PROCEED TO WERE-DONE
    GO TO PERFORM-IT
    .
WERE-DONE.
    DISPLAY the-counter
    GOBACK
    .
A.
    ADD 1 TO the-counter
    GO TO RETURN-TO
    .
B.
    ADD 2 TO the-counter
    GO TO RETURN-TO
    .
PERFORM-IT.
    GO TO
    .
RETURN-TO.
    GO TO
    .

Or:

    ALTER RETURN-TO TO PROCEED TO NEXT-PARA
    GO TO A
    .
NEXT-PARA.
    ALTER RETURN-TO TO PROCEED TO WERE-DONE
    GO TO B
    .
WERE-DONE.
    DISPLAY the-counter
    GOBACK
    .
A.
    ADD 1 TO the-counter
    GO TO RETURN-TO
    .
B.
    ADD 2 TO the-counter
    GO TO RETURN-TO
    .
RETURN-TO.
    GO TO
    .
On an IBM Mainframe and prior to the greatly-improved optimisation
with their COBOL II compilers, that would avoid a whole heap of code
generated "after" the end of the paragraph, which determines whether a
PERFORM was active, so a return is needed, otherwise glibbly dribbling
on.

Of course applied piecemeal to reuse different pieces of code from
different points in the business-logic (multiple exits from the
paragraphs, effectively, even though only one exit, they are multiple
because they are to multiple potential locations) then you start to see
the torture that can ensue. "If I put an ALTER there, and another one
there, then I don't need to change anything else". Making a piece of
code into a PERFORMed paragraph or SECTION when it is originally in a
fall-through program takes a little more to do.

Obviously, if you don't start out with a fall-though program in the
first place, it is different. Reusing a piece of code doesn't have to
become opaque.

The only-24-hours-in-a-day part of "performance" were much more serious
with much slower machines.

Remember also that the big fall-through program is on 12,000 punched
cards. "Restructuring" is more than trivial effort. You're being paid to
make the small change, not paid to take three days to do it and two
weeks to test it, even if the program is a bit nicer afterwards (no way
at all to rewrite the whole program).

I was lucky and never had to use punched cards, but I worked with a lot
of people who did, and they made me fully aware of the many problems.

Access via terminal to programs stored on disk probably had a greater
impact on structured programming than we can imagine today.

Simon Sobisch added some commentary to the commentary:

> Remember also that the big fall-through program is on 12,000 punched
> cards. "Restructuring" is more than trivial effort.

Missing option to restructure the program because of punchcard - this is
the best explanation for "why did someone ever wanted to use ALTER"
ever!

BTW: I'm one of the "this COBOL program needs a restructure"
programmers. Not "just because" but "because it's very likely that
someone [possibly I myself] needs to change the program again - if I
took 2 hours to understand the program logic this time I'll invest 2
other hours to make sure this won't happen again, restructure it, change
the comments to actually match the logic, ..".  And restructuring old
sources is sometimes the best option to deeply understand their logic,
enabling you to find the bug / place where to add the feature missing.
If you're in a hurry: keep the changed version for later when you have
the time to test it and just copy the necessary changes into the
original version for now.

I'm thankfull for having the sources on disk and multiline editors with
syntax highlighting, options to copy-and-paste, search [and replace],
... It's a wonderful time for programmers!

4.1.19   ALTERNATE

Defines an ALTERNATE key for ISAM data structures.

SELECT file
    ASSIGN TO filename
    ACCESS MODE IS RANDOM
    RECORD KEY IS key-field
    ALTERNATE KEY IS alt-key WITH DUPLICATES.

4.1.20   AND

A logic operator. COBOL rules of precedence are; NOT, AND, OR.

IF field = "A" AND num = 3
    DISPLAY "got A3"
END-IF

COBOL also allows abbreviated combined relational conditions.

IF NOT (a NOT > b AND c AND NOT d)
   code
END-IF

is equivalent to

IF NOT (((a NOT > b) AND (a NOT > c)) AND (NOT (a NOT > d)))
    code
END-IF

4.1.21   ANY

Allows for any value is TRUE in an EVALUATE statement WHEN clause.

EVALUATE  TRUE  ALSO  TRUE
    WHEN a > 3  ALSO  ANY      *> b can be any value **
        PERFORM a-4-b-any
    WHEN a = 3  ALSO  b = 1
        PERFORM a-3-b-1
END-EVALUATE

4.1.22   ANYCASE

Not yet implemented. Will allow case insensitive match of currency symbols with FUNCTION NUMVAL-C.

4.1.23   ARE

Allows for multiple conditional VALUES.

01 cond-1   PIC X.
   88 first-truth   VALUES ARE "A" "B" "C".
   88 second-truth  VALUES ARE "X" "Y" "Z".

4.1.24   AREA

Controls SORT, MERGE and RECORD data definitions.

I-O-CONTROL.
    SAME RECORD AREA FOR file1, file2.

4.1.25   AREAS

Plural readability option for AREA

SAME RECORD AREAS

4.1.26   ARGUMENT-NUMBER

Holds the number of OS parsed command line arguments, and can act as the explicit index when retrieving ARGUMENT-VALUE data. ARGUMENT-NUMBER can be used in ACCEPT FROM and DISPLAY UPON expressions.

ACCEPT command-line-argument-count FROM ARGUMENT-NUMBER

DISPLAY 2 UPON ARGUMENT-NUMBER
ACCEPT indexed-command-line-argument FROM ARGUMENT-VALUE

See COMMAND-LINE for more information on the unparsed command invocation string.

4.1.27   ARGUMENT-VALUE

Returns the next command line argument. This post from John on opencobol.org is an excellent idiom for parsing command line arguments without too much worry as to the order.

       >>source format is free
*>*****************************************************************
*> Author:    jrls (John Ellis)
*> Date:      Nov-2008
*> Purpose:   command line processing
*>*****************************************************************
identification division.
program-id. cmdline.
data division.
*>
working-storage section.
*>******************************************
01 argv                 pic x(100) value spaces.
   88 recv                         value "-r", "--recv".
   88 email                        value "-e", "--email".
   88 delivered                    value "-d", "--delivered".
01 cmdstatus            pic x    value spaces.
   88 lastcmd                    value "l".
01 reptinfo.
   05 rept-recv         pic x(30) value spaces.
   05 rept-howsent      pic x(10) value spaces.
*>
procedure division.
 0000-start.
*>
    perform until lastcmd
         move low-values        to argv
         accept argv            from argument-value
         if argv > low-values
            perform 0100-process-arguments
         else
            move "l"            to cmdstatus
         end-if
    end-perform
    display reptinfo.
    stop run.
*>
 0100-process-arguments.
*>
     evaluate true
         when recv
            if rept-recv = spaces
               accept rept-recv from argument-value
            else
               display "duplicate " argv
            end-if
         when email
            move "email"        to rept-howsent
         when delivered
            move "delivered"    to rept-howsent
         when other display "invalid switch: " argv
     end-evaluate.

Example run:

./cmdline --recv "john ellis" -e -f
invalid switch: -f
john ellis                    email

4.1.28   ARITHMETIC

Not yet implemented feature of the not yet implemented OPTIONS paragraph of the IDENTIFICATION DIVISION.

4.1.29   AS

Can be used to change the external linkage name of a program or function.

PROGRAM-ID. program-name AS literal.

Part of a CONSTANT clause

01 const-id AS 123.
01 str-const AS "abc".

Can also change the reference name for EXTERNAL items.

01 shared-data pic x(4) is external AS "newname".

4.1.30   ASCENDING

COBOL table support.

01 CLUBTABLE.
   05 MEMBER-DATA OCCURS 1 TO 7000000000 TIMES
        DEPENDING ON PEOPLE
        ASCENDING KEY IS HOURS-DONATED.

Sort order control.

sort clubtable ASCENDING key hours-donated

Also see DESCENDING.

4.1.31   ASCII

American Standard Code for Information Interchange.

One of the two main character encodings supported by GnuCOBOL.

See EBCDIC for the other common encoding used in COBOL programming.

ASCII to EBCDIC conversion the GnuCOBOL way

SPECIAL-NAMES.
ALPHABET ALPHA IS ASCII.
ALPHABET BETA IS EBCDIC.

PROCEDURE DIVISION.
INSPECT variable CONVERTING ALPHA TO BETA

But note that that is only safe for character data. Numeric fields will not always convert properly with that mechanism.

See the GNU/Linux command man ascii for a full list of ASCII characters and numeric values. Keep in mind that COBOL is an ordinal system, and counting starts at one. See FUNCTION ORD FUNCTION CHAR for some details of this potential issue when programming.

4.1.32   ASSIGN

Assign a name to a file or other external resource.

SELECT input-file
ASSIGN TO "filename.ext"
SELECT input-file
ASSIGN USING DYNAMIC identifier
SELECT input-file
ASSIGN TO EXTERNAL identifier

The actual filename used is dependent on a configuration setting. Under default configuration settings, filename-mapping is set to yes.

See What are the GnuCOBOL compile time configuration files? for details.

# If yes, file names are resolved at run time using
#   environment variables.
# For example, given ASSIGN TO "DATAFILE", the actual
#   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.
#
# Value: 'yes', 'no'
filename-mapping: yes

So, under GNU/Linux, bash shell

$ export DD_DATAFILE='/tmp/opencobol.dat'
$ ./myprog

the program will find the data in /tmp/opencobol.dat

$ export DD_DATAFILE='/tmp/other.dat'
$ ./myprog

This run of the same program will find the data in /tmp/other.dat

As shown in the sample .conf comments, the order of environment variable lookup proceeds through three environment variables before using a literal as the filename.

  • DD_DATAFILE
  • dd_DATAFILE
  • DATAFILE
  • and finally “DATAFILE”

DATAFILE is the name used in

ASSIGN TO name

The name can be any valid COBOL identifier, or string leading to a valid operating system filename.

GnuCOBOL also accepts device name qualifiers such as:

  • PRINTER
  • PRINT
  • DISC
  • DISK
  • TAPE
  • RANDOM
  • CARD-PUNCH
  • CARD-READER
  • CASSETTE
  • INPUT
  • INPUT OUTPUT
  • MAGNETIC TAPE
  • OUTPUT
  • LINE ADVANCING
  • DISPLAY
  • KEYBOARD

KEYBOARD comes in especially handy with CGI programming, giving access to POST data which is set up by web servers as the standard in for CGI programs.

Many of the device qualifiers are accepted as syntax but have no logical effect on handling. For instance, a CASSETTE or CARD-PUNCH qualifier is simply ignored, with the native operating system managing the attributes of any filenames that happen to reference any non file system devices.

4.1.33   AT

Controls cursor positioning of ACCEPT and DISPLAY screen oriented verbs.

*> Display at line 1, column 4 <*
 DISPLAY "Name:" AT 0104
*> Accept starting at line 1, column 10 for length of field <*
 ACCEPT name-var AT 0110

AT syntax allows for 4 digit and 6 digit values. llcc or lllccc, where the total length determines if the line and column subfields are treated as 2 or 3 digits each.

4.1.34   ATTRIBUTE

Manage screen field attributes. SET ON OFF for

SET screen-name ATTRIBUTE BLINK OFF

4.1.35   AUTHOR

An informational statement in the IDENTIFICATION DIVISION. Deemed OBSOLETE, but still commonly seen. GnuCOBOL treats this as a to end of line comment phrase, periods are not required. Multiples AUTHOR statements are allowed.

4.1.36   AUTO

Automatic cursor flow to next field in screen section.

4.1.38   AUTOMATIC

LOCK MODE IS AUTOMATIC. See MANUAL and EXCLUSIVE for more LOCK options.

4.1.40   AWAY-FROM-ZERO

A rounding MODE. See ROUNDED for more details on the different modes.

AWAY-FROM-ZERO +2.49 -2.49 +2.50 -2.50 +3.49 -3.49 +3.50 -3.50 +3.51 -3.51
Becomes +3 -3 +3 -3 +4 -4 +4 -4 +4 -4

A COBOL example (also demonstrating user names that are the same as in context compiler words):

GCobol IDENTIFICATION   DIVISION.
       PROGRAM-ID.      prog.
       ENVIRONMENT      DIVISION.
       CONFIGURATION    SECTION.
       DATA             DIVISION.
       WORKING-STORAGE  SECTION.
       01  X               PIC 9 VALUE 0.
       01  AWAY-FROM-ZERO  PIC 9 VALUE 0.
       PROCEDURE        DIVISION.
           COMPUTE X ROUNDED MODE AWAY-FROM-ZERO
                   AWAY-FROM-ZERO = 1.1
           DISPLAY X ", " AWAY-FROM-ZERO NO ADVANCING
           STOP RUN.

displays:

2, 1

X being rounded away from zero from 1.1 to 2.

4.1.41   B-AND

Not yet implemented BIT field operation. See What STOCK CALL LIBRARY does GnuCOBOL offer? CBL_AND for alternatives allowing bitwise operations.

4.1.42   B-NOT

Not yet implemented BIT field operation. See What STOCK CALL LIBRARY does GnuCOBOL offer? CBL_NOT for alternatives allowing bitwise operations.

4.1.43   B-OR

Not yet implemented BIT field operation. See What STOCK CALL LIBRARY does GnuCOBOL offer? CBL_OR for alternatives allowing bitwise operations.

For example:

GCobol >>SOURCE FORMAT IS FIXED
      *> ***************************************************************
      *> Author:    Brian Tiffin
      *> Date:      20110626
      *> Purpose:   Demonstrate alternative for B-OR
      *> Tectonics: cobc -x bits.cob
      *> ***************************************************************
       identification division.
       program-id. bits.

       data division.
       working-storage section.
       01 s1 pic 999 usage comp-5.
       01 t2 pic 999 usage comp-5.
       01 len   pic 9.
       01 result usage binary-long.

      *> ***************************************************************
       procedure division.
       move 2 to s1
       move 4 to t2
       move 1 to len

      *> CBL_OR takes source, target and length value  2 OR 4 is 6.   **
       call "CBL_OR" using s1 t2 by value len returning result end-call
       display s1 space t2 space len space result

       goback.
       end program bits.

giving:

$ cobc -x bits.cob
$ ./bits
002 006 1 +0000000000

s1 is read, t2 is read and written.

For a COBOL source code solution to BIT operations, Paul Chandler was nice enough to publish BITWISE.cbl and a full listing is included at BITWISE.

4.1.44   B-XOR

Not yet implemented BIT field operation. See What STOCK CALL LIBRARY does GnuCOBOL offer? CBL_XOR for alternatives allowing bitwise operations.

4.1.45   BACKGROUND-COLOR

05 BLANK SCREEN BACKGROUND-COLOR 7 FOREGROUND-COLOR 0.

4.1.47   BASED

Defines unallocated working storage. The address of the variable will need to be set before access or a run-time error will occur.

01 based-var PIC X(80) BASED.

A sample posted by [human]

GCobol*-----------------------------------------------------------------
       IDENTIFICATION DIVISION.
       PROGRAM-ID. 'MEMALL'.
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       SPECIAL-NAMES. DECIMAL-POINT IS COMMA.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
       DATA DIVISION.
       FILE SECTION.
      *
       WORKING-STORAGE SECTION.
      *
       77  mychar      pic x.
       01  REC-TEST BASED.
           03 REC-TEST-PART1 PIC X(5500000).
           03 REC-TEST-PART2 PIC X(0100000).
           03 REC-TEST-PART3 PIC X(1200000).
           03 REC-TEST-PART4 PIC X(1200000).
           03 REC-TEST-PART5 PIC X(1700000).
      *-----------------------------------------------------------------
       LINKAGE SECTION.
      *-----------------------------------------------------------------
       PROCEDURE DIVISION.
       declaratives.
       end declaratives.
      *-----------------------------------------------------------------
       main section.
       00.
           FREE ADDRESS OF REC-TEST
           display 'MEMALL loaded and REC-TEST FREEd before ALLOCATE'
           accept   mychar
      *
           IF ADDRESS OF REC-TEST = NULL
              display 'REC-TEST was not allocated before'
           ELSE
              display 'REC-TEST was allocated before'
           END-IF
           accept  mychar
      *
           ALLOCATE  REC-TEST
           move all '9' to REC-TEST
           display 'REC-TEST allocated and filled with '
                REC-TEST (1:9)
           accept  mychar
      *
           IF ADDRESS OF REC-TEST = NULL
              display 'REC-TEST was not allocated before'
              ALLOCATE  REC-TEST
              display 'REC-TEST allocated again, filled with '
                   REC-TEST (1:9)
           ELSE
              display 'REC-TEST was allocated before'
           END-IF
           accept  mychar
      *
      *
           FREE ADDRESS OF REC-TEST
           display 'REC-TEST FREEd'
           accept  mychar
      *
           stop run
      *
           continue.
       ex. exit program.
      *-----------------------------------------------------------------
      *--- End of program MEMALL ---------------------------------------

4.1.48   BEEP

Ring the terminal bell during DISPLAY output. Alias for BELL

DISPLAY "Beeeeep" LINE 3 COLUMN 1 WITH BEEP END-DISPLAY.

4.1.49   BEFORE

Sets up a PERFORM loop to test the conditional before execution of the loop body. See AFTER for the alternative. BEFORE is the default.

MOVE 1 TO counter
PERFORM WITH TEST BEFORE
    UNTIL counter IS GREATER THAN OR EQUAL TO limiter
        CALL "subprogram" USING counter RETURNING result END-CALL
        MOVE result TO answers(counter)
        ADD 1 TO counter END-ADD
END-PERFORM

Also used with the WRITE verb.

WRITE record-name
    BEFORE ADVANCING some-number LINES

And to control how the INSPECT verb goes about its job.

INSPECT character-var TALLYING
   the-count FOR ALL "tests" BEFORE "prefix"

And in the declaratives for REPORT SECTION control.

USE BEFORE REPORTING
 ...

4.1.50   BELL

Ring the terminal bell during DISPLAY output. Alias for BEEP

DISPLAY "Beeeeep" LINE 3 COLUMN 1 WITH BELL END-DISPLAY.

4.1.51   BINARY

01 result PIC S9(8) USAGE BINARY

4.1.52   BINARY-C-LONG

Extension.

With GnuCOBOL’s tight integration with the C Application Binary Interface the compiler authors have built in support that guarantees a native system C long value being the same bit size between COBOL and C modules. This increases coverage of the plethora of open C library functions that can be directly used with the CALL verb. Including cases where callback functions that require long stack parameters (that can’t as easily be wrapped in thin C code layers) can now be used more effectively and safely.

4.1.53   BINARY-CHAR

Defines an 8 bit usage item.

4.1.54   BINARY-DOUBLE

Defines a 64 bit usage item.

4.1.55   BINARY-INT

Extension. Equivalent to BINARY-LONG 32 bit data item.

4.1.56   BINARY-LONG

32 bit native USAGE modifier.

BINARY-LONG SIGNED    -2147483648 [-2**31] < n < 2147483648 [2**31]
BINARY-LONG UNSIGNED                    0 <= n < 4294967296 [2**32]

Will almost fit in an S9(9) or 9(9). In COBOL, picture 9(10) doesn’t really work either, as the 10 digits needed to hold 4,294,967,296 would allow for 9,999,999,999 and that actually requires 34 bits of information.

The largest value that COBOL can hold in 32 bits and still represent the decimal value required by PICTURE 9, is 999,999,999. It is a fundamental difference between base-2 and base-10 representations.

For PIC 9(9) USAGE COMP-5, COBOL allocates 32 bits. Just don’t try and go to a billion in binary and then display it as USAGE DISPLAY as things won’t be right.

There was longstanding misinformation here, pointed out by Simon, the old, wrong documentation was S9(8). Repeat. Wrong. Don’t believe everything you read here. Verify it, just in case.

As an example, with GnuCOBOL in January of 2016

GCobol >>SOURCE FORMAT IS FREE
       identification division.
       program-id. comp32.

       environment division.
       configuration section.
       repository. function all intrinsic.

       data division.
       working-storage section.
       01 comp32               PIC S9(9) USAGE COMP-5.
       01 comp34               PIC S9(10) USAGE COMP-5.

       procedure division.
       display "comp32 s9(9)  usage comp-5 length: "
           function length(comp32) " and "
           function byte-length(comp32) " byte-length"

       display "comp34 s9(10) usage comp-5 length: "
           function length(comp34) " and "
           function byte-length(comp34) " byte-length"
       display space

       perform varying tally from 1 by 1 until tally > 3
           evaluate tally
               when 1 display "2 ** 29 ok"
               when 2 display "2 ** 30 DISPLAY IS TRUNCATED FOR comp32"
               when 3 display "2 ** 31 size error detected for comp32"
           end-evaluate

           compute comp32 = 2 ** (28 + tally)
               on size error perform soft-exception
               not on size error
                   display "comp32 = 2 ** (28 + " tally ") =  " comp32
           end-compute

           compute comp34 = 2 ** (28 + tally)
               on size error perform soft-exception
               not on size error
                   display "comp34 = 2 ** (28 + " tally ") = " comp34
           end-compute
           display space
       end-perform
       goback.
      *> ***************************************************************

      *> informational warnings and abends
       soft-exception.
         display space upon syserr
         display "--Exception Report-- " upon syserr
         display "Time of exception:   " current-date upon syserr
         display "Module:              " module-id upon syserr
         display "Module-path:         " module-path upon syserr
         display "Module-source:       " module-source upon syserr
         display "Exception-file:      " exception-file upon syserr
         display "Exception-status:    " exception-status upon syserr
         display "Exception-location:  " exception-location upon syserr
         display "Exception-statement: " exception-statement upon syserr
         display space upon syserr
       .

       hard-exception.
           perform soft-exception
           stop run returning 127
       .

       end program comp32.

With a run sample of:

prompt$ cobc -xj -debug comp32.cob
comp32 s9(9)  usage comp-5 length: 000000004 and 000000004 byte-length
comp34 s9(10) usage comp-5 length: 000000008 and 000000008 byte-length

2 ** 29 ok
comp32 = 2 ** (28 + 00001) =  +536870912
comp34 = 2 ** (28 + 00001) = +0536870912

2 ** 30 DISPLAY IS TRUNCATED FOR comp32
comp32 = 2 ** (28 + 00002) =  +073741824
comp34 = 2 ** (28 + 00002) = +1073741824

2 ** 31 size error detected for comp32

--Exception Report--
Time of exception:   2016013107083456-0500
Module:              comp32
Module-path:         /home/btiffin/lang/cobol/forum/comp32
Module-source:       comp32.cob
Exception-file:      00
Exception-status:    EC-SIZE-OVERFLOW
Exception-location:  comp32; ; 31
Exception-statement: COMPUTE

comp34 = 2 ** (28 + 00003) = +2147483648

You can’t blame COBOL for the erroneous display of 2 ** 30 when converted to decimal. You can’t blame the computer either. You can only lament the tragedy that is the human machine interface, and rise to the challenge.

4.1.57   BINARY-LONG-LONG

Extension. Equivalent to BINARY-DOUBLE.

4.1.58   BINARY-SHORT

16 bit native USAGE. Will fit in S9(5), or 9(5), but note that due to the differences in decimal and binary representations, the picture may end up with invalid decimal data. 32767 will display properly with pic s9(5), 70000 (for example) will not, as it requires more then 16 bits in base-2.

4.1.59   BIT

Not yet implemented. See What STOCK CALL LIBRARY does GnuCOBOL offer? for alternatives allowing bitwise operations.

4.1.60   BLANK

05 BLANK SCREEN BACKGROUND-COLOR 7 FOREGROUND-COLOR 0.

4.1.62   BLOCK

A supported, but ignored, file control block control clause. Most POSIX operating systems do not honour attempts to override file and record block sizing. Some TAPE device drivers may honour the setting, but GnuCOBOL simply ignores the phrase.

FD file-name
  BLOCK CONTAINS 1 TO n RECORDS

4.1.63   BOOLEAN

An as yet unsupported data category.

4.1.64   BOTTOM

A LINAGE setting for the number of lines to use for a bottom margin. The bottom margin defaults to zero lines.

FD  mini-report
      linage is 16 lines
          with footing at 15
          lines at top 2
          lines at bottom 2.

4.1.65   BY

VARYING loop variable step value. GnuCOBOL requires this clause and there is no default step value. Can be any numeric type or value, postitive or negative, integer or floating point.

PERFORM the-procedure
    VARYING step-counter FROM 1 BY step-size
    UNTIL step-counter > counter-limit

4.1.66   BYTE-LENGTH

Human incisors average about 16mm.

More to the point, BYTE-LENGTH returns the length, in bytes, of a data item. See FUNCTION BYTE-LENGTH. This will become more important as NATIONAL data item support increases in the GnuCOBOL implementations.

4.1.67   CALL

The GnuCOBOL CALL verb provides access to library functions. It accepts a string literal, or name stored in an identifier, when resolving the control flow transfer address. This assumes the called procedure returns, COBOL controlled flow proceeding in sequence to the statement immediately following the END-CALL.

The USING phrase allows argument passing to and from subprograms. GnuCOBOL includes internal rules for the data representation of the call stack entities, that depend on the COBOL PICTURE and USAGE clauses. subprogram return values are captured with a RETURNING phrase.

_images/call-statement.png

See What STOCK CALL LIBRARY does GnuCOBOL offer? for a list of CALL entry names that are included in the GnuCOBOL run-time support libraries.

For some old, historical information see http://open-cobol.sourceforge.net/historical/open-cobol/C-Interface.html

CALL is the verb that opens up access to the plethora of C based ABI libraries. A plethora, and the standard C library is accessible without explicit linkage as a bonus.

One item of note is C pointers. Especially those passed around as handles. When calling a C routine that returns a handle, the RETURNING identifier will receive a C pointer. To use that handle in later CALL statements, the argument from COBOL should usually be passed BY VALUE. This passes the C pointer, not the address of the COBOL identifier, as the default BY REFERENCE argument handling would do.

Below is a sample that allows fairly carefree use of CBL_OC_DUMP during development. ON EXCEPTION CONTINUE.

GCobol*>>SOURCE FORMAT IS FIXED
      *> ***************************************************************
      *> Author:    Brian Tiffin
      *> Date:      20110701
      *> Purpose:   Try C library formatted printing, and CALL exception
      *> Tectonics: cobc -x callon.cob
      *>        or  cobc -x callon.cob CBL_OC_DUMP.cob
      *> ***************************************************************
       identification division.
       program-id. callon.

       data division.
       working-storage section.
       01 result      usage binary-long.

       01 pie         usage float-short.
       01 stuff       pic x(12) value 'abcdefghijkl'.

      *> ***************************************************************
       procedure division.
       move 3.141592654 to pie

      *> Get a dump of the memory at pie, but don't stop if not linked
       call "CBL_OC_DUMP" using pie 4 on exception continue end-call

      *> Call C's printf, abort if not available
       call static "printf" using
           "float-short: %10.8f" & x"0a00"
           by value pie
           returning result
       end-call
       display pie space length of pie space result

      *> Get a dump of the memory used by stuff, don't stop if no link
       call "CBL_OC_DUMP" using stuff 12 on exception continue end-call

      *> Get a dump of the memory used by stuff, abort if not linked <*
       call "CBL_OC_DUMP" using stuff 12 end-call

       goback.
       end program callon.

See What is CBL_OC_DUMP? for details of the subprogram.

A run-time session shows:

$ cobc -x callon.cob
$ ./callon
float-short: 3.14159274
3.1415927 4 +0000000024
libcob: Cannot find module 'CBL_OC_DUMP'
$ cobc -x callon.cob CBL_OC_DUMP.cob
$ ./callon

Offset  HEX-- -- -- -5 -- -- -- -- 10 -- -- -- -- 15 --   CHARS----1----5-
000000  db 0f 49 40                                       ..I@............

float-short: 3.14159274
3.1415927 4 +0000000024

Offset  HEX-- -- -- -5 -- -- -- -- 10 -- -- -- -- 15 --   CHARS----1----5-
000000  61 62 63 64 65 66 67 68 69 6a 6b 6c               abcdefghijkl....


Offset  HEX-- -- -- -5 -- -- -- -- 10 -- -- -- -- 15 --   CHARS----1----5-
000000  61 62 63 64 65 66 67 68 69 6a 6b 6c               abcdefghijkl....

So, the first CALL to CBL_OC_DUMP doesn’t ‘fail’ as the ON EXCEPTION CONTINUE traps the condition and lets the program carry on without a dump displayed. The last CALL does abend the program with ‘Cannot find module’ when CBL_OC_DUMP is not compiled in, to show the difference.

4.1.67.1   CALL STATIC

Sometimes it is just nice to link in subprograms at compile time.

GnuCOBOL 2.0 and up supports a -K”name” (multiple uses allowed) cobc option to inform the compiler to link that call module statically, into the object code. By default CALL is dynamic.

CALL STATIC "puts" USING a-zstring END-CALL

will link to the libc function at compile time, and not rely on the run-time dynamic linker. Works well with Cygwin compiles, which can have a tough time finding the POSIX support DLLs at run-time. See STATIC.

4.1.67.2   CALL STDCALL

Changes the call frame handler. With STDCALL, called subprogram are responsible for parameter stack cleanup adjustment, not the caller. _std modifier is generated in the intermediate C sources. See STDCALL.

4.1.67.3   RETURNING OMITTED

One sticky point with COBOL and CALL. Foreign functions, C in particular, can specify void return. That means no value is placed on top of the call frame. Unless told otherwise, COBOL will assume that value is there, possibly popping it off, and corrupting, a call frame stack. To CALL void C, or assembler routine, for another case, use CALL ... RETURNING OMITTED.

4.1.68   CANCEL

Virtual cancel of a module is supported. Physical cancel support is on the development schedule.

_images/cancel-statement.png

4.1.69   CAPACITY

Not yet supported.

4.1.70   CD

A control clause of the as yet unsupported COMMUNICATION DIVISION.

4.1.71   CENTER

An as yet unsupported keyword.

4.1.72   CF

Short form for CONTROL FOOTING, a clause used in REPORT SECTION.

4.1.73   CH

Short form for CONTROL HEADING, a clause used in PAGE descriptors in the REPORT SECTION.

4.1.74   CHAIN

Not yet supported.

Invokes a subprogram, with no return of control implied. The chained program unit virtually becomes the main program within the run unit.

4.1.75   CHAINING

Passes procedure division data through WORKING-STORAGE from the command line. Technically from the argc/argv parameters used by the C ABI.

Note that this does not pass CALL ... USING data, but command line arguments.

GCOBOL identification division.
       program-id. chained.

       environment division.
       configuration section.
       repository.
           function all intrinsic.

       data division.
       working-storage section.
       01 str                  pic x(80).

       procedure division chaining str.
       display "In chained with :" trim(str) ":"

       accept str from command-line
       display "COMMAND-LINE    :" trim(str) ":"

       goback.
       end program chained.

Sample run:

prompt$ cobc -x -j='"this is a test"' chained.cob
In chained with :this is a test:
COMMAND-LINE    :this is a test:

And now, invoked from a CALL, the CHAINING data is still that of the command line. Even though the call “works”, CALL does not set command arguments just because the called program uses CHAINING.

Having said that, the COMMAND-LINE special register can be modified before hand. In the sample run below, the chained.cob program gets both the actual first element from the operating system argv, AND the special register set in caller.cob.

A caller program.

GCOBOL identification division.
       program-id. caller.

       data division.
       working-storage section.

       procedure division.

       display "new COMMAND-LINE argument value" upon command-line
       call "chained" using "** this is NOT passed by chaining **"

       goback.
       end program caller.
prompt$ cobc -x caller.cob chained.cob
prompt$ ./caller "this is the original argv"
In chained with :this is the original argv:
COMMAND-LINE    :new COMMAND-LINE argument value:

CHAINING str receives the operating system value, not the argument used by CALL. On top of that, the CHAINING value is not a copy of the current COMMAND-LINE special register, but the actual operating system argument.

The module has the explicitly set internal COMMAND-LINE special register value from caller.cob, and the chained argv. This might come in handy, but is probably not something you’d want to do to someone that has to maintain your code; if you want them to know what is going on and where data is coming from.

4.1.76   CHARACTER

PADDING CHARACTER IS

A soon to be obsolete feature.

4.1.77   CHARACTERS

A multi use keyword.

Used in SPECIAL-NAMES

GCobol >>SOURCE FORMAT IS FIXED
      *> ***************************************************************
      *> Author:    Brian Tiffin
      *> Date:      20101031
      *> Purpose:   Try out SYMBOLIC CHARACTERS
      *> Tectonics: cobc -x figurative.cob
      *> Rave:      GnuCOBOL is stone cold cool
      *> ***************************************************************
       identification division.
       program-id. figurative.

       environment division.
       configuration section.
       special-names.
           symbolic characters TAB is 10
                               LF  is 11
                               CMA is 45.

       data division.
       working-storage section.
       01 a-comma pic x(1) value ",".
       01 lots-of-commas pic x(20).

      *> ***************************************************************
       procedure division.
       display
           "thing" TAB "tabbed thing" LF
           "and" TAB "another tabbed thing" LF
           "other" CMA " things"

       move a-comma to lots-of-commas
       display "MOVE a-comma : " lots-of-commas

       move CMA to lots-of-commas
       display "MOVE symbolic: " lots-of-commas

       goback.
       end program figurative.

Output:

$ cobc -x figuratives.cob
$ ./figuratives
thing   tabbed thing
and     another tabbed thing
other, things
MOVE a-comma : ,
MOVE symbolic: ,,,,,,,,,,,,,,,,,,,,

Used in INSPECT

INSPECT str TALLYING TALLY FOR CHARACTERS BEFORE INITIAL ','

INSPECT str REPLACING CHARACTERS BY '*' AFTER INITIAL ':'

Used in a File Description FD

FD file-name
   BLOCK CONTAINS integer-1 TO integer-2 CHARACTERS
   RECORD IS VARYING IN SIZE FROM integer-5 TO integer-6 CHARACTERS
      DEPENDING ON identifier-1.

In the above case, identifier-1 will set a record size limit for write, but will be filled with the actual length read for reads. Handy for LINE SEQUENTIAL files and getting at how many characters come in on each line.

Used in ALLOCATE

ALLOCATE 100 * cell-size CHARACTERS RETURNING heap-pointer

4.1.78   CLASS

Used to create character classes in SPECIAL-NAMES. In some circumstances, character classes can be used to validate data in a very concise way.

ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES.
CLASS octals IS '0' THRU '7'.

CLASS host-class IS 'A' THROUGH 'Z'
                    'a' THROUGH 'z'
                    '0' THROUGH '9'
                    '-', '.'.

...

PROCEDURE DIVISION.
IF user-value IS NOT octals
    DISPLAY "Sorry, not a valid octal number"
ELSE
    DISPLAY user-value
END-IF

IF network-host IS NOT host-class
    DISPLAY "Invalid (pre international domain name standard) host"
END-IF

4.1.79   CLASS-ID

An as yet unsupported Object COBOL class identifier clause.

4.1.80   CLASSIFICATION

An as yet unsupported source code internationalization clause.

4.1.81   CLOSE

Close an open file. GnuCOBOL will implicitly close all open resources at termination of a run unit and will display a warning message stating it did so, and the danger of potentially unsafe termination.

CLOSE input-file

4.1.82   COB-CRT-STATUS

Predefined PIC 9(4) special register for CRT status. This field is not predefined if an explicit

CRT STATUS IS user-field

is used in a SPECIAL-NAMES paragraph.

4.1.83   COBOL

A PROCEDURE DIVISION qualifier, laying down a normal COBOL entry point.

See EXTERN for the other type of program entry qualifier.

4.1.84   CODE

A clause of a report descriptor, RD.

4.1.85   CODE-SET

An as yet unsupported data internationalization clause.

4.1.87   COLLATING

Allows definition within a program unit of a character set.

OBJECT-COMPUTER. name.
  PROGRAM COLLATING SEQUENCE IS alphabet-1.

4.1.89   COLUMN

  • A REPORT SECTION RD descriptor clause.
  • Also used for positional DISPLAY and ACCEPT, which implicitly uses SCREEN SECTION style ncurses screen IO.
DISPLAY var-1 LINE 1 COLUMN 23

When using the condensed form of extended AT, the first two (or three) digits are LINE and the last two (or three) digits are COLUMN. These literal values can be either four or six digits.

DISPLAY "Text" AT 0203
DISPLAY "Text" AT 002101 WITH REVERSE-VIDEO

4.1.90   COLUMNS

An RD clause, plural of COLUMN.

4.1.91   COMMA

A SPECIAL-NAMES clause supporting commas in numeric values versus the default period decimal point. COBOL was way ahead of the internationalization curve, and this feature has caused compiler writers no little grief in its time, a challenge they rise to and deal with for the world’s benefit.

DECIMAL POINT IS COMMA

4.1.92   COMMAND-LINE

Provides access to command line arguments.

ACCEPT the-args FROM COMMAND-LINE END-ACCEPT

COMMAND-LINE is a single character field.

See ARGUMENT-VALUE and ARGUMENT-NUMBER for access to separate shell expanded arguments.

The special system library CBL_GC_HOSTED can also be used to access the commonly referred to argc and argv argument count and array of separate argument string pointers that are passed to main funtions by POSIX friendly operating systems.

4.1.93   COMMIT

Flushes ALL current locks, synching file I/O buffers. GnuCOBOL supports safe transactional processing with ROLLBACK capabilities. Assuming the ISAM handler configured when building the compiler can support LOCK_

_images/commit-statement.png

In tandem with ROLLBACK, the commitment boundary is from OPEN to first COMMIT or ROLLBACK, then until the next COMMIT or ROLLBACK, repeating until CLOSE.

Only a single commitment point is ever active, per file.

4.1.94   COMMON

PROGRAM-ID. CBL_OC_PROGRAM IS COMMON PROGRAM.

Ensures a nested subprogram is also available to other nested subprograms with a program unit hierarchy.

4.1.95   COMMUNICATION

currently (January 2017) unsupported section, but see Does GnuCOBOL support Message Queues? for an alternative.

4.1.96   COMP

A binary USAGE form. Short for COMPUTATIONAL. By COBOL standard, this form is an implementation depedent form. Usually one of the fastest native forms, but not that safe when transferring data between machines, even those compiled with the same version of GnuCOBOL, as it depends on hardware platform.

4.1.97   COMP-1

Equivalent of FLOAT-SHORT single precision floating point. GnuCOBOL uses IEEE 754 standard floating point representation.

Alias for COMPUTATIONAL-1

4.1.98   COMP-2

Equivalent of FLOAT-LONG double precision floating point. GnuCOBOL uses IEEE 754 standard floating point representation.

See COMPUTATIONAL-2

4.1.99   COMP-3

PACKED DECIMAL binary storage form. See COMPUTATIONAL-3

4.1.101   COMP-5

A hardware preferred binary storage form, with allowed PICTURE. This can lead to some interesting edge cases.

For example; PIC S9(4) will need 2 bytes of storage. That leads to values between -32768 and +32767. But, a PIC S9(4) is limited to display usage in the range -9999 to +9999. Internal and external view can differ considerably.

Dual PIC and BINARY fields need to be treated with care and respect. COMP-5 is subject to external high order truncation when displayed by PICTURE and during PICTURE based MOVE instructions. The compiler option -fnotrunc can modify this behaviour and may display fields wider than the PICTURE.

COMP-5 is always native memory storage order, independent of the binary-byteorder configuration setting.

COMP-5 will share the same byte order forms as C programs on the same platform.

COMP-5 byte order may not be suitable for some network data when using common Intel chip sets, as the internet uses big-endian form and Intel is commonly little-endian layout.

A compile time test, using the Compiler Directive Facility is available with a predefined ENDIAN symbol. It will hold BIG or LITTLE at compile time.

>>IF ENDIAN = "BIG"
big end code
>>END-IF

>>IF ENDIAN = "LITTLE"
little end code
>>END-IF

See COMPUTATIONAL-5

4.1.102   COMP-6

Unsigned COMP-3, UNSIGNED PACKED.

See COMPUTATIONAL-6 and COMPUTATIONAL-3

4.1.103   COMP-X

A binary USAGE format with PICTURE data allowed to be any alphanumeric type. PIC X data can be treated as computational numerics with COMP-X.

Stored in memory dependent on the binary-byteorder configuration setting. Can be native or big-endian order. COMP-X allows binary data that use PIC X definitions. By default, GnuCOBOL stores BINARY data in big-endian order.

Please note that the binary-byteorder setting can vary from compile to compile and the same source code can produce different binary fields when this setting is changed between compiles. GnuCOBOL keeps an internal flag attached to each and every field that determines whether byte reording code is needed when managing platform byte order and current ‘COBOL’ byte order.

Unless involved in cross platform data sharing or networking, programmers will rarely have to worry about this as the compiler keeps track and swaps bytes as needed.

*> Modified: 2016-04-30/01:52-0400
 COPY sample-template REPLACING
 ==:DATABOOK:== BY
 ==

 01 from-x     pic x(4) comp-x value "WXYZ".

 ==
 ==:CODEBOOK:== BY
 ==

 display from-x
 add 1 to from-x
 display from-x

 ==
 .

Giving:

$ cobc -xj compx-sample.cob
sample-template.cob: 12: Warning: Numeric value is expected
465407834
465407835

See Sample shortforms for the sample-template listing.

COMPUTATIONAL-X is the long form alias of COMP-X.

4.1.104   COMPUTATIONAL

Implementors choice binary storage form; GnuCOBOL is a big-endian default. With most Intel personal computers and operating systems like GNU/Linux, COMPUTATIONAL-X will run faster, as internal byte swapping can be avoided.

The default byte-order is controlled by compile time configuration though, and care must be taken when making assumptions if data is being transferred over the network or between machines. See What are the GnuCOBOL compile time configuration files? and What is rumtime.cfg? for more details on these low level issues. As this is compile time control, looking at current settings may not be accurate compared to the executable, which may have been compiled when different settings where in place. This can really only be verified from inside the executable itself, with a byte-order test at runtime.

An example for byte-order testing can be found in the CBL_OC_DUMP sources

OCDUMP 77  byline                pic 999    usage comp-5.

       TEST-ENDIAN SECTION.
       00.
      *    Number-bytes are shuffled in Big-Little endian
           move 128 to byline
           set address of byte to address of byline
           if function ord(byte) > 0
              set  is-big-endian-yes to true
           else
              set  is-big-endian-no  to true
           end-if
      *
           continue.
       ex. exit.

Where the first byte of the value 128 in byline will be zero for little-endian and non-zero for big-endian storage. Endian order testing has to make assumptions about known bit layouts of multiple byte numeric data to be reliable and it is difficult to make this determination by external means. Native order is not always applicable as GnuCOBOL will add code to swap bytes depending on the byte-order configuration setting at compile time if needed.

4.1.105   COMPUTATIONAL-1

Single precision float. Equivalent to FLOAT-SHORT.

4.1.106   COMPUTATIONAL-2

Double precision float. Equivalent to FLOAT-LONG.

4.1.107   COMPUTATIONAL-3

Equivalent to PACKED DECIMAL. Packed decimal is stored as two digits per byte, always sign extended and influenced by a .conf setting binary-size. COMPUTATIONAL-6 is UNSIGNED PACKED.

4.1.108   COMPUTATIONAL-4

Equivalent to BINARY.

4.1.110   COMPUTATIONAL-6

Unsigned packed decimal form, see COMPUTATIONAL-3.

4.1.111   COMPUTATIONAL-X

Binary form, allowing PIC X data to be treated as a computational numeric value.

4.1.112   COMPUTE

Computational arithmetic.

COMPUTE circular-area = radius ** 2 * FUNCTION PI END-COMPUTE
_images/compute-statement.png

GnuCOBOL supports the normal gamut of arithmetic expressions.

  • Add +
  • Subtract -
  • Multiply *
  • Divide /
  • Raise to power **

Order of precedence rules apply.

  1. unary minus, unary plus
  2. exponentiation
  3. multiplication, division
  4. addition, subtraction

Spaces and expressions

Due to COBOL allowing dash in user names, care must be taken to properly space arithmetic expressions.

Some examples of seemingly ambiguous and potentially dangerous code

GCobol*> ***************************************************************
       identification division.
       program-id. computing.

       data division.
       working-storage section.
       01 answer pic s9(8).
       01 var    pic s9(8).

      *> ***************************************************************
       procedure division.
       compute answer = 3*var-1 end-compute

       goback.
       end program computing.

That is not three times var minus one, it is 3 times var-1 GnuCOBOL will complain.

$ cobc -x computing.cob
computing.cob:18: Error: 'var-1' is not defined

whew, saved!

GCobol*> ***************************************************************
       identification division.
       program-id. computing.

       data division.
       working-storage section.
       01 answer pic s9(8).
       01 var    pic s9(8).
       01 var-1  pic s9(8).

      *> ***************************************************************
       procedure division.
       compute answer = 3*var-1 end-compute

       goback.
       end program computing.

With the above source, the compile will succeed.

$ cobc -x computing.cob

GnuCOBOL will, (properly, according to standard), compile this as three times var-1. Not saved, if you meant 3 times var minus 1.

GnuCOBOL programmers are strongly encouraged to use full spacing inside COMPUTE statements.

GCobol*> ***************************************************************
       identification division.
       program-id. computing.

       data division.
       working-storage section.
       01 answer pic s9(8).
       01 var    pic s9(8).
       01 var-1  pic s9(8).

      *> ***************************************************************
       procedure division.
       compute
           answer = 3 * var - 1
           on size error
               display "Problem, call the ghost busters"
           not on size error
               display "All good, answer is within range"
       end-compute

       goback.
       end program computing.

COMPUTE supports ON SIZE ERROR, NOT ON SIZE ERROR conditionals for safety, and many ROUNDED modifiers for bankers. There are eight (8) different roundings.

COMPUTE
    total ROUNDED MODE NEAREST-AWAY-FROM-ZERO =
      total - amount * rate / time-span
END-COMPUTE

With the default being NEAREST-AWAY-FROM-ZERO with ROUNDED, and TRUNCATION when the ROUNDED keyword is not present.

4.1.113   CONDITION

As yet unsupported USE AFTER EXCEPTION CONDITION clause.

4.1.115   CONSTANT

A data definition keyword allowing for constant values. These values cannot be passed by reference, nor can the data name be used with ADDRESS OF.

01 enumerated-value CONSTANT AS 500.
01 some-string      CONSTANT AS "immutable value".

4.1.116   CONTAINS

An FD clause:

FD a-file RECORD CONTAINS 80 CHARACTERS.

4.1.117   CONTENT

A CALL clause that controls how arguments are passed.

CALL "subprog" USING BY CONTENT alpha-var.

alpha-var will not be modifiable by subprog, as a copy is passed.

See REFERENCE and VALUE for the other CALL argument controls.

4.1.118   CONTINUE

A placeholder, no operation verb. That’s not quite true, continue breaks out of the current statement, doing nothing else.

_images/continue-statement.png

The sample below isn’t good design, only a poor example.

if action-flag = "C" or "R" or "U" or "D"
    continue
else
    display "invalid action-code"
end-if

A pretty handy use for continue, while developing and coming to grips with C structures and unknown datums:

call "CBL_OC_DUMP" using cstruct ON EXCEPTION CONTINUE end-call

Including CBL_OC_DUMP in the cobc tectonics, causes a hex dump. Without linkage; no runtime error, just continue, avoiding a stop run.

4.1.119   CONTROL

REPORT SECTION clause for setting control break data fields.

4.1.120   CONTROLS

REPORT SECTION clause for setting control break data fields.

4.1.121   CONVERSION

Not yet implemented.

An ignored screen attribute.

4.1.122   CONVERTING

A clause of the INSPECT verb.

INSPECT X CONVERTING "012345678" TO "999999999".

GnuCOBOL supports an extension statement, TRANSFORM which is identical in effect to INSPECT CONVERTING.

4.1.123   COPY

The COBOL include preprocessor verb. Source text is inserted from an external text file, sometimes called a copybook, and treated as if it was typed into the current source file (with some possible REPLACING modifications during the copy include operation).

_images/copy-directive.png

Also see REPLACE and Does GnuCOBOL support COPY includes?.

For example

Given cobweb-gtk-data-preamble.cpy

*> Repository default data names
 01 gtk-window-record.
    05 gtk-window       usage pointer.
    05 gwr-pointer      usage pointer.
    05 gwr-number       usage binary-long.
*> ...

with cobweb-gtk.cob

*> Include some data
 data division.
 working-storage section.

 01 important-field pic x.

 COPY cobweb-gtk-data-preamble.

 01 more-working-store pic xx.

 procedure division.

 COPY cobweb-gtk-preamble.

 move new-button(new-box(new-window("Put up a GUI"),
     "An OK button", "cobweb-gtk-clicked"))
   to extraneous

 goback.
 end program sample.

then cobc -x cobweb-gtk.cob which will start up a compile, with part of the data division loaded with some ease of use data field names that may ship with FUNCTION-ID repositories, perhaps the REPOSITORY list itself in another copybook, and perhaps some init code needed by the library or application.

See What extensions are used if cobc is called with/without “-ext” for COPY? for details regarding the search path used by COPY.

4.1.123.1   COPY REPLACING

In the real world, copybooks are often created with some form of tag. The tag is replaced at compile time so that multiple copies of the same record layout can be used without having conflicting names.

copybook.cpy

01 :tag:-record.
   05 :tag:-keyfield           PIC X(8).
   05 :tag:-description        PIC X(32).
   05 :tag:-itemlist           PIC X(8) OCCURS subitems TIMES.

contrived.cob

identification division.
program-id. contrived.

data division.
working-storage section.

COPY copybook REPLACING ==:tag:== BY ==ws==   subitems BY 16.
COPY copybook REPLACING ==:tag:== BY ==old==  subitems BY 0.

procedure division.
move "abcdefgh" to ws-keyfield old-keyfield

PERFORM read-next-partnumber

if ws-keyfield equal old-keyfield
    display "lookup didn't change key " ws-keyfield
else
    display "new key " ws-keyfield " was " old-keyfield
end-if

goback.

read-next-partnumber.
move "hgfedcba" to ws-keyfield
.

end program contrived.

4.1.123.2   Full stop and COPY

Many samples in this document are single sentence COBOL programs. No periods in the procedure division, except the last and only one, required to end a COBOL program source unit. This is likely an extremely rare style of production COBOL development. There will be numerous required full stop periods in the procedure division, to separate sections and named paragraphs in almost all useful COBOL programs. Mentioning this here to setup the context for the following notice.

Of note:

COPY statements always needs a period, regardless of where they are in the source program. The period terminates the COPY statement, and does NOT get included in the compilation source.

4.1.125   CORRESPONDING

Move, or do arthimetic, any and all sub fields with matching names within records.

01 bin-record.
   05 first-will usage binary-short.
   05 second-will usage binary-long.
   05 this-wont-move usage binary-long.
   05 third-will usage binary-short.
01 num-record.
   05 first-will pic 999.
   05 second-will pic s9(9).
   05 third-will pic 999.
   05 this-doesnt-match pic s9(9).

move corresponding bin-record to num-record
display
    first-will in num-record
    second-will in num-record
    third-will in num-record

4.1.126   COUNT

Sets the count of characters set in an UNSTRING substring.

From the GnuCOBOL Programmer’s Guide’s UNSTRING entry.

UNSTRING Input-Address
    DELIMITED BY "," OR "/"
    INTO
        Street-Address DELIMITER D1 COUNT C1
        Apt-Number DELIMITER D2 COUNT C2
        City DELIMITER D3 COUNT C3
        State DELIMITER D4 COUNT C4
        Zip-Code DELIMITER D5 COUNT C5
END-UNSTRING

4.1.127   CRT

SPECIAL-NAMES.
    CONSOLE IS CRT
    CRT STATUS is identifier-1.

CONSOLE IS CRT allows “CRT” and “CONSOLE” to be used interchangeably on DISPLAY but this is a default for newer GnuCOBOL implementations.

CRT STATUS IS establishes a PIC 9(4) field for screen ACCEPT status codes. There is also an implicit COB-CRT-STATUS register defined for all programs, that will be used if no explicit field is established.

4.1.129   CURRENCY

SPECIAL-NAMES.
    CURRENCY SIGN IS literal-1.

Default currency sign is the dollar sign “$”.

4.1.130   CURSOR

Tracks the line/column location of screen ACCEPT.

SPECIAL-NAMES.
    CURSOR IS identifier-2.

identifier-2 is to be declared as PIC 9(4) or 9(6). If 4, the field is LLCC. With 9(6) it is LLLCCC where L is line and C is column, zero relative.

4.1.131   CYCLE

A clause that causes EXIT PERFORM to return to the top of a loop. See FOREVER for an example.

4.1.132   DATA

A magical DIVISION. One of COBOL’s major strength is the rules surrounding the DATA DIVISION and pictorial record definitions.

4.1.133   DATA-POINTER

An as yet unsupported Object COBOL feature.

4.1.134   DATE

An ACCEPT source. 6 digit and 8 digit Gregorian dates.

  1. ACCEPT ident-1 FROM DATE
  2. ACCEPT ident-2 FROM DATE YYYYMMDD
 identification division.
 program-id. dates.

 data division.
 working-storage section.
 01 date-2nd
    03 date-yy   pic 9(2).
    03 date-mm   pic 9(2).
    03 date-dd   pic 9(2).
 01 date-3rd
    03 date-yyyy pic 9(4).
    03 date-mm   pic 9(2).
    03 date-dd   pic 9(2).

 procedure division.
 accept date-2nd from date end-accept

*> Just before the 3rd millennium, programmers admitted     <*
*>   that 2 digit year storage was a bad idea and ambiguous <*
 accept date-3rd from date yyyymmdd end-accept

 display date-2nd space date-3rd

 goback.
 end program dates.
./dates
110701 20110701

4.1.135   DATE-COMPILED

An informational paragraph in the IDENTIFICATION DIVISION. Deemed OBSOLETE, but still in use. GnuCOBOL treats this as a comment paragraph.

4.1.136   DATE-MODIFIED

An informational paragraph in the IDENTIFICATION DIVISION. Deemed OBSOLETE, but still in use. GnuCOBOL treats this as a comment paragraph.

4.1.137   DATE-WRITTEN

An informational paragraph in the IDENTIFICATION DIVISION. Deemed OBSOLETE, but still in use. GnuCOBOL treats this as a comment paragraph.

4.1.138   DAY

An ACCEPT source. Access the current date in Julian form. Returns yyddd and yyyyddd formats.

  1. ACCEPT ident-1 FROM DAY
  2. ACCEPT ident-2 FROM DAY YYYYDDD
GCobol >>SOURCE FORMAT IS FIXED
      *> ***************************************************************
      *> Author:    Brian Tiffin
      *> Date:      2011182 (July 01)
      *> Purpose:   Accept from day in Julian form
      *> Tectonics: cobc -x days.cob
      *> ***************************************************************
       identification division.
       program-id. days.

       data division.
       working-storage section.
       01 julian-2nd.
          03 julian-yy   pic 9(2).
          03 julian-days pic 9(3).
       01 julian-3rd.
          03 julian-yyyy pic 9(4).
          03 julian-days pic 9(3).

       procedure division.
       accept julian-2nd from day end-accept

      *> Just before the 3rd millennium, programmers admitted     <*
      *> that 2 digit year storage was a bad idea and ambiguous   <*
       accept julian-3rd from day yyyyddd end-accept

       display julian-2nd space julian-3rd

       goback.
       end program days.
$ make days
cobc -W -x days.cob -o days
$ ./days
11182 2011182

4.1.139   DAY-OF-WEEK

An ACCEPT source. Single digit day of week. 1 for Monday, 7 for Sunday.

accept the-day from day-of-week

4.1.140   DE

Report Writer shortcut for DETAIL. This author found this type of shortcut very unCOBOL, until trying to layout a report, when it made a lot more practical sense in FIXED form COBOL.

4.1.141   DEBUGGING

A SOURCE-COMPUTER clause and DECLARATIVE phrase.

ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER mine
  WITH DEBUGGING MODE.

DEBUGGING MODE can also be toggled on with the -fdebugging-line cobc option, and will compile in ‘D’ lines.

PROCEDURE DIVISION.
DECLARATIVES.
decl-debug section.
  USE FOR DEBUGGING ON ALL PROCEDURES
decl-paragraph.
  DISPLAY "Why is this happening to me?"
END DECLARATIVES.

USE FOR DEBUGGING sets up a section that is executed when the named section is entered. Powerful. It can also name a file, and the debug section is evaluated after open, close, read, start etc. Identifiers can be also be named and the debug section will trigger when referenced (usually after).

4.1.142   DECIMAL-POINT

Allows internationalization for number formatting. In particular

IDENTIFICATION DIVISION.
PROGRAM-ID. 'MEMALL'.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES. DECIMAL-POINT IS COMMA.

will cause GnuCOBOL to interpret numeric literals along the lines of 123,45 as one hundred twenty three and forty five one hundredths.

DECIMAL-POINT IS COMMA, while world friendly, can be the cause of ambiguous parsing and care must be taken by developers that use comma to separate parameters to FUNCTIONs.

4.1.143   DECLARATIVES

An imperative entry that can control exception handling of file operations and turn on debug entry points.

procedure division.
declaratives.
handle-errors section.
    use after standard error procedure on filename-1.
handle-error.
    display "Something bad happened with " filename-1
.
helpful-debug section.
    use for debugging on main-file.
help-me.
    display "Just touched " main-file
.
end declaratives.

4.1.144   DEFAULT

A multi-use clause used in

4.1.145   DELETE

  • Allows removal of records from RELATIVE and INDEXED files.
  • Allows removing files by COBOL name, including all associated support files.
_images/delete-statement.png
DELETE filename-1 RECORD
  INVALID KEY
    DISPLAY "no delete"
  NOT INVALID KEY
    DISPLAY "record removed"
END-DELETE

4.1.145.1   GC 2.0

GnuCOBOL 2.0 and up, allows for file deletes.

DELETE FILE
    filename-1 filename-2 filename-3
END-DELETE

will remove files by FD SELECT name, including any implicit .idx key index files used by ISAM handlers, or delete by literal filesystem name.

4.1.146   DELIMITED

A fairly powerful keyword used with the STRING and UNSTRING verbs. Accepts literals and the BY SIZE modifier.

STRING null-terminated
    DELIMITED BY LOW-VALUE
    INTO no-zero
END-STRING

4.1.147   DELIMITER

Tracks which delimiter was used for a substring in an UNSTRING operation.

From Gary’s OCic.cbl

UNSTRING Expand-Code-Rec
    DELIMITED BY ". " OR " "
    INTO SPI-Current-Token
    DELIMITER IN Delim
    WITH POINTER Src-Ptr
END-UNSTRING

4.1.148   DEPENDING

Sets a control identifier for variable OCCURS table definitions.

01 TABLE-DATA.
   05 TABLE-ELEMENTS
       OCCURS 1 TO 100 TIMES DEPENDING ON crowd-size
       INDEXED BY cursor-var.
     10 field-1 PIC X.

4.1.149   DESCENDING

Controls a descending sort and/or retrieval order, with

  • SORT filename ON DESCENDING KEY alt-key
  • OCCURS 1 TO max-size TIMES DESCENDING KEY key-for-table

4.1.150   DESTINATION

Currently unsupported data descriptor. Part of VALIDATE.

4.1.151   DETAIL

A report descriptor detail line control clause.

4.1.152   DISABLE

An unsupported COMMUNICATION SECTION control verb.

4.1.153   DISC

Alternate spelling for DISK.

4.1.154   DISK

A SELECT devicename phrase.

ASSIGN TO DISK USING dataname

Alternative spelling of DISC is allowed.

4.1.155   DISPLAY

A general purpose output, and operating environment setting verb.

_images/display-statement.png
  • prints values to default console or other device
  • set the current ARGUMENT-NUMBER influencing subsequent access ACCEPT FROM ARGUMENT-VALUE statements
  • specify explicit COMMAND-LINE influencing subsequent access with ACCEPT FROM COMMAND-LINE, but not ARGUMENT-VALUE access
  • sets environment variables, as part of a two step process. (Use the more concise SET ENVIRONMENT instead)
    1. DISPLAY “envname” UPON ENVIRONMENT-NAME
    2. DISPLAY “envname-value” UPON ENVIRONMENT-VALUE
DISPLAY "First value: " a-variable " and another string"

DISPLAY "1" 23 "4"

The setting of environment variables does not influence the owning process shell.

DISPLAY "ENVNAME" UPON ENVIRONMENT-NAME
DISPLAY "COBOL value" UPON ENVIRONMENT-VALUE
     ON EXCEPTION stop run
     NOT ON EXCEPTION continue
END-DISPLAY
CALL "SYSTEM" USING "echo $ENVNAME"

gives:

$ ENVNAME="parent shell value"
$ ./disps
COBOL value
$ echo $ENVNAME
parent shell value

Extended attributes (requires WITH keyword):

_images/extended-display.png

Please note: DISPLAY datafield WITH extended-attributes will cause initialization of the extended IO Terminal User Interface system. That means all further IO to the display is subject to the rules of SMCUP and RMCUP.

4.1.156   DIVIDE

Highly precise arithmetic.

_images/divide-statement.png

Supports various forms:

  • DIVIDE INTO
  • DIVIDE INTO GIVING
  • DIVIDE BY GIVING
  • DIVIDE INTO with REMAINDER
  • DIVIDE BY with REMAINDER

For example:

DIVIDE dividend BY divisor GIVING answer ROUNDED REMAINDER r
    ON SIZE ERROR
        PERFORM log-division-error
        SET division-error TO TRUE
    NOT ON SIZE ERROR
        SET division-error TO FALSE
END-DIVIDE

The 2014 standard requires conforming implementations to use 1,000 digits of precision for intermediate results. There will be no rounding errors when properly calculating financials in a COBOL program.

4.1.157   DIVISION

Ahh, sub-divisions. I think my favourite is the DATA DIVISION. It gives COBOL a distinctive and delicious flavour in a picturesque codescape.

Divisions must be specified in the order below within each source program unit.

  1. IDENTIFICATION DIVISION.
  2. ENVIRONMENT DIVISION.
  3. DATA DIVISION.
  4. PROCEDURE DIVISION.

A handy mnemonic may be “I Enter Data Properly”.

GnuCOBOL is flexible enough to compile files with only a PROCEDURE DIVISION, and even then it really only needs a PROGRAM-ID. See What is the shortest GnuCOBOL program? for an example.

4.1.158   DOWN

Allows decrement of an index control or pointer variable.

SET ind-1 DOWN BY 2

SET ptr-1 DOWN BY 8

Also used for SCREEN SECTION scroll control.

SCROLL DOWN 5 LINES

4.1.159   DUPLICATES

Allows duplicate keys in indexed files.

SELECT filename
  ALTERNATE RECORD KEY IS altkey WITH DUPLICATES

Also for SORT control.

SORT filename ON DESCENDING KEY keyfield
  WITH DUPLICATES IN ORDER
  USING sort-in GIVING sort-out.

4.1.160   DYNAMIC

A file access mode allowing runtime control over SEQUENTIAL and RANDOM access for INDEXED and RELATIVE ORGANIZATION.

SELECT filename
  ORGANIZATION IS RELATIVE
  ACCESS MODE IS DYNAMIC

4.1.161   EBCDIC

Extended Binary Coded Decimal Interchange Code.

A character encoding common to mainframe systems, therefore COBOL, therefore GnuCOBOL. Different than ASCII and GnuCOBOL supports both through efficient mappings. See https://en.wikipedia.org/wiki/EBCDIC for more info.

ASCII to EBCDIC conversion the GnuCOBOL way

SPECIAL-NAMES.
ALPHABET ALPHA IS NATIVE.
ALPHABET BETA IS EBCDIC.

PROCEDURE DIVISION.
INSPECT variable CONVERTING ALPHA TO BETA

4.1.162   EC

An unsupported short form for USE AFTER EXCEPTION CONDITION

4.1.163   EGI

An unsupported COMMUNICATION SECTION word.

4.1.164   ELSE

Alternate conditional branch point.

IF AGE IS ZERO
   DISPLAY "Cigar time"
ELSE
   DISPLAY "What is it with kids anyway?"
END-IF

For multi branch conditionals, see EVALUATE.

4.1.165   EMI

An unsupported COMMUNICATION SECTION word.

4.1.166   EMPTY-CHECK

Alias for the REQUIRED screen attribute.

4.1.167   ENABLE

An unsupported COMMUNICATION SECTION control verb.

4.1.168   END

Ends things.

  • END FUNCTION
  • END PROGRAM
  • END DECLARATIVES

4.1.169   END-ACCEPT

Explicit terminator for ACCEPT.

4.1.170   END-ADD

Explicit terminator for ADD.

4.1.171   END-CALL

Explicit terminator for CALL.

4.1.172   END-CHAIN

Not yet implemented.

Will be an explicit terminator for CHAIN.

4.1.173   END-COMPUTE

Explicit terminator for COMPUTE.

4.1.174   END-DELETE

Explicit terminator for DELETE.

4.1.175   END-DISPLAY

Explicit terminator for DISPLAY.

Many samples from this FAQ used to use END-DISPLAY, they are being purged, as of October 2015, unless necessary.

4.1.176   END-DIVIDE

Explicit terminator for DIVIDE.

4.1.177   END-EVALUATE

Explicit terminator for EVALUATE.

4.1.178   END-IF

Explicit terminator for IF.

4.1.179   END-MULTIPLY

Explicit terminator for MULTIPLY.

4.1.180   END-OF-PAGE

A LINAGE phrase used by WRITE controlling end of page imperative clause.

4.1.181   END-PERFORM

Explicit terminator for PERFORM.

4.1.182   END-READ

Explicit terminator for READ.

4.1.183   END-RECEIVE

Explicit terminator for RECEIVE.

4.1.184   END-RETURN

Explicit terminator for RETURN.

4.1.185   END-REWRITE

Explicit terminator for REWRITE.

4.1.187   END-START

Explicit terminator for START.

4.1.188   END-STRING

Explicit terminator for STRING.

4.1.189   END-SUBTRACT

Explicit terminator for SUBTRACT.

4.1.190   END-UNSTRING

Explicit terminator for UNSTRING.

4.1.191   END-WRITE

Explicit terminator for WRITE.

4.1.192   ENTRY

Allows for CALL entry points without being fully specified subprograms. Great for defining callbacks required by many GUI frameworks.

See Does GnuCOBOL support the GIMP ToolKit, GTK+? for an example.

4.1.193   ENTRY-CONVENTION

An as yet unsupported clause.

4.1.194   ENVIRONMENT

Divisional name. And allows access to operating system environment variables. GnuCOBOL supports

within the ENVIRONMENT DIVISION.

Also a context sensitive keyword for access to the process environment variables.

  • SET ENVIRONMENT “env-var” TO value
  • ACCEPT var FROM ENVIRONMENT “env-var” END-ACCEPT

4.1.195   ENVIRONMENT-NAME

Provides access to the running process environment variables.

4.1.196   ENVIRONMENT-VALUE

Provides access to the running process environment variables.

4.1.197   EO

An unsupported short form for USE AFTER EXCEPTION OBJECT

4.1.198   EOL

ERASE to End Of Line.

4.1.199   EOP

LINAGE clause short form for END-OF-PAGE.

4.1.200   EOS

ERASE to End Of Screen.

4.1.201   EQUAL

Conditional expression to compare two data items for equality.

4.1.202   EQUALS

Conditional expression to compare two data items for equality.

4.1.203   ERASE

A screen section data attribute clause that can control which portions of the screen are cleared during DISPLAY, and ACCEPT.

01 form-record.
   02 first-field PIC xxx
      USING identifier-1
      ERASE EOL.

4.1.204   ERROR

A DECLARATIVES clause that can control error handling.

USE AFTER STANDARD ERROR PROCEDURE ON filename-1

Program return control.

STOP RUN WITH ERROR STATUS stat-var.

4.1.205   ESCAPE

Programmer access to escape key value during ACCEPT.

ACCEPT identifier FROM ESCAPE KEY END-ACCEPT