1   OpenCOBOL FAQ

OpenCOBOL
Authors:
Brian Tiffin [btiffin]

Answers, quotes and contributions:
John Ellis [jrls_swla], Vincent Coen, Jim Currey, Bill Klein [wmklein],
Ganymede, Simon Sobisch [human], Rildo Pragana, Sergey Kashyrin,
Federico Priolo, Frank Swarbrick, Angus, DamonH, Parhs, Gerald Chudyk

Compiler by:
Roger While [Roger],
Keisuke Nishida [Keisuke],
(with the invaluable assistance of many others)

Special credits to
Gary Cutler author of the OpenCOBOL Programmers Guide
Joseph James Frantz for hosting and advocacy [aoirthoir]
Version:1.1, October 19th, 2013
Status:Final. Superceded by GNU Cobol
Copyright:Copyright © 2008-2013 Brian Tiffin
License:
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation License,
Version 1.3 or any later version published by the Free Software
Foundation; with no Invariant Sections, no Front-Cover Texts and
no Back-Cover Texts. A copy of the license is included in the
ChangeLog:ChangeLog

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?

OpenCOBOL FAQ

1.1   What is OpenCOBOL?

OpenCOBOL is an open-source COBOL compiler. OpenCOBOL implements a substantial part of the COBOL 85 and COBOL 2002 standards, as well as many extensions of the existent COBOL compilers.

OpenCOBOL translates COBOL into C and compiles the translated code using the native C compiler. You can build your COBOL programs on various platforms, including Unix/Linux, Mac OS X, and Microsoft Windows.

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

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.

1.3   How is OpenCOBOL licensed?

The compiler is licensed under GNU General Public License.

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

All source codes are copyright by the respective authors.

What that means, roughly, is:

You are allowed to write OpenCOBOL programs that use the libcob run time
library however you like.  Closed, proprietary, commercial use is allowed
and encouraged.  You can ship programs in binary form as you wish.

Modifications to the compiler itself, MUST provide access to source code and
be licensed under the GNU GPL.  This ensures that no one is allowed to call
modified sources their own, nor deny anyone else the chance to copy and
re-distribute the compiler source code, including your local changes.

Please note: 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.

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

1.4   What platforms are supported by OpenCOBOL?

OpenCOBOL 1.0 the current official release version, 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

OpenCOBOL 1.1, 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

1.5   Are there pre-built OpenCOBOL packages

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

A Debian Advanced Package Tool binary package exists for OpenCOBOL 1.0 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.

1.5.1   kiska.net repository

Also check out kiska.net for binary builds on various platforms. Thanks to Sergey Kashyrin.

1.5.2   sourceforge

There are OpenCOBOL 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 mininum. Maybe more as time goes on.

1.7   How complete is OpenCOBOL?

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.

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

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

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

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

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

THIS IS THE NEW TEXT.

Note

While OpenCOBOL 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 OpenCOBOL?

This author believes so. For an open source implementation of COBOL, OpenCOBOL 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.

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

Many people. In particular Keisuke Nishida and Roger While.

See the THANKS file in the source code archive for more names of people that have worked on the OpenCOBOL 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 OpenCOBOL 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.

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

1.11   Does OpenCOBOL pass the NIST Test Suite?

The National Institute of Standards and Technology, NIST, maintains a COBOL 85 implementation verification suite of tests. An archive of the tests can be found at

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

OpenCOBOL passes many of the tests included in the NIST sponsored COBOL 85 test suite. While it passes over 9000 of the tests, OpenCOBOL 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 OpenCOBOL over some 374 programs/modules and includes thousands of test passes.

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

Advanced facilities:

  IF - Intrinsic Function tests

With the addition of GLOBAL support, the OpenCOBOL 1.1 pre-release fails none of the attempted tests.

The summary.log from a run in February 2009:

------ Directory Information -------   --- Total Tests Information ---
Module Programs Executed Error Crash   Pass Fail Deleted Inspect Total
------ -------- -------- ----- -----  ----- ---- ------- ------- -----
NC           92       92     0     0   4363    0       6      11  4380
SM           15       15     0     0    290    0       3       1   294
IC           24       24     0     0    246    0       4       0   250
SQ           81       81     0     0    512    0       6      81   599
RL           32       32     0     0   1827    0       5       0  1832
IX           39       39     0     0    507    0       1       0   508
ST           39       39     0     0    278    0       0       0   278
SG            5        5     0     0    193    0       0       0   193
OB            5        5     0     0     16    0       0       0    16
IF           42       42     0     0    732    0       0       0   732
------ -------- -------- ----- -----  ----- ---- ------- ------- -----
Total       374      374     0     0   8964    0      25      93  9082

1.11.1   What’s missing?

OpenCOBOL 1.1 does not include support for, or limits tests within the:

Advanced facilities:

  RW - REPORT SECTION tests
  CM - COMMUNICATION SECTION tests
  SG - Segment tests
  DB - Debugging facilities tests
  OB - Obsolete facilities tests

sections.

1.12   What about OpenCOBOL 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 OpenCOBOL developer will likely be using.

OpenCOBOL, 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 at http://home.comcast.net/~wmklein/DOX/TELCO.txt 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.

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

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

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

1.13   Can OpenCOBOL be used for CGI?

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

For those developers looking to serve OpenCOBOL applications on hosted systems and no super user privileges, see How do I use LD_RUN_PATH with OpenCOBOL? for some pointers.

1.14   Does OpenCOBOL support a GUI?

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

Third party extensions for Tcl/Tk and bindings for GTK+ do allow for graphical user interfaces. See Does OpenCOBOL support the GIMP ToolKit, GTK+? and Can OpenCOBOL interface with Tcl/Tk?.

1.14.1   GTK

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

1.14.2   Tcl/Tk

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

1.14.3   Vala, WebKit

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

1.15   Does OpenCOBOL have an IDE?

Yes and no. There is no IDE that ships with the product. The add1tocobol team is currently (February 2013) at work creating extensions for the GNAT Programming Studio. This is working out quite nicely and will likely be the IDE of choice for the add1tocobol OpenCOBOL developers.

See Can the GNAT Programming Studio be used with OpenCOBOL? for more information.

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

Many text editors have systems in place for invoking compilers. SciTE, Crimson Editor, vi and emacs to name but a few of the hundreds that support edit/compile/test development cycles.

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

1.16   Can OpenCOBOL be used for production applications?

Depends. OpenCOBOL 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 analyzed and risks evaluated before commitment to production use.

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

There may be a time when commercial support of OpenCOBOL is offered, but at the time of writing no known offering exists.

Search google just in case!

And yes, OpenCOBOL is used 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   Nagasaki Prefecture

Reported on opencobol.org, The Nagasaki Prefecture, population 1.44 million and 30,000 civil employees is using OpenCOBOL 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.2   Stories from Currey Adkins

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

OpenCOBOL 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 OpenCOBOL and his company is a community minded company. http://www.curreyadkins.com

1.16.3   Public Accounting

Another from opencobol.org

As part of an initial study of COBOL compilers for finding an alternative to
that of MicroFocus, 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 MicroFocus, 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.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 “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.

The COBUG site COBOL User Groups is also a wonderful resource for OpenCOBOL developers.

This is highly subject to change, but currently (February 2013) a Draft of 20xx is available at http://www.cobolstandard.info/j4/index.htm and in particular http://www.cobolstandard.info/j4/files/std.zip

Note

While OpenCOBOL 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.18   Where can I get more information about OpenCOBOL?

Current project activities are at SourceForge. The opencobol.org website is probably a good place search as well. add1tocobol.com is a place to find out about a few of the fan initiatives. (An older archive has been stashed at http://oldsite.add1tocobol.com)

1.18.1   The OpenCOBOL Programmer’s Guide

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

1.19   Can I help out with the OpenCOBOL project?

Absolutely. Visit the opencobol.org website 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 an OpenCOBOL mailing list? for some details. OpenCOBOL is a GPL licensed open source project and while [Roger] is the lead developer he is quite open to code submissions. Having a central point of development allows for consistency and the very high level of quality control enjoyed by OpenCOBOL users.

1.19.1   Translation Efforts

A new project has started to see native language support in the cobc compile and run-time systems. Please see http://www.opencobol.org/modules/newbb/viewtopic.php?topic_id=1127&forum=1 for details if you think you can help.

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.

...

1.20   Is there an OpenCOBOL mailing list?

Yes. Visit opencobol.org for details. The OpenCOBOL development mailing list is graciously hosted by SourceForge. The ML archive is available at http://sourceforge.net/mailarchive/forum.php?forum_name=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 currently (February 2013) a Draft of 20xx is available at http://www.cobolstandard.info/j4/index.htm and in particular http://www.cobolstandard.info/j4/files/std.zip

Note

While OpenCOBOL 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 OpenCOBOL source codes?

Absolutely. Being an open source system, all sources that are used to build the compiler are available and free.

The opencobol.org site has links to 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.

1.22.2   A Doxygen pass across the compiler source code

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

Is there OpenCOBOL 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 runtime is interacting with the operating system.

1.22.4   What was used to color 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.

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

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

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

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, 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.1   on SourceForge

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

Other projects include:

1.25.2   add1tocobol

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

1.25.3   Stickleback

Wim Niemans’ Project Stickleback. http://www.mycobol.net/ and http://stickleback.nlbox.com/

1.25.4   other places

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

  • A common disrepect 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 OpenCOBOL 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

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

1.26.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 fails when run. Fails as poetry, fails as code. Your welcome.

One in cbrain

 72 . 65
. 73 . 75 .
 85 . 42

Displaying HAIKU and returning 42.

2   History

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.

Admiral Grace Hopper is affectionately referred to as the mother of the COBOL language as she and her previous work with FLOW-MATIC greatly influenced the specifications of the first COBOL.

Standards have been published for:

  • COBOL-68
  • COBOL-74
  • COBOL-85
  • COBOL-2002
  • Draft work for COBOL-20xx is currently (February 2013) underway

and these roughly correspond to the year they were produced. Note the y2k flavour of four digit naming occurred after the millennium change.

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

See the Wikipedia entry for COBOL for a lot more details.

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.

Note

While OpenCOBOL 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 OpenCOBOL?

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.

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.

2.4   What is the current version of OpenCOBOL?

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 occured publically until February, 2009. The pre-release source tar can be found at OpenCOBOL 1.1 with installer instructions at OpenCOBOL 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 in development at http://sourceforge.net/projects/open-cobol

2.4.1   Building the current version

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

$ tar xvf open-cobol-1.1.tar.gz
$ cd open-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.

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

2.4.2   occurlrefresh

If you build a pre-release OC1.1, 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 (February 2013) 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.

3   Using OpenCOBOL

Using OpenCOBOL

3.1   How do I install OpenCOBOL?

Installation instructions can be found at OpenCOBOL Install.

3.1.1   From source with GNU/Linux

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

3.1.2   Debian

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

$ apt-get install open-cobol

3.1.3   Fedora

From the main Fedora repositories

$ yum install open-cobol

3.1.4   Windows

Build from sources under Cygwin or MinGW. Follow the instructions from the site listed above, or read the OC_GettingStarted_Windows document by [wmklein] available online at

Also see What is the current version of OpenCOBOL?.

3.1.5   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.2   What are the configure options available for building OpenCOBOL?

configure is a defacto 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 OpenCOBOL, the ./configure script accepts --help as a command line option to display all of the available configuration choices.

`configure' configures OpenCOBOL 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   (OpenCOBOL) enable experimental code (Developers only!)
  --enable-param-check    (OpenCOBOL) 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>          (OpenCOBOL) specify the C compiler used by cobc
  --with-seqra-extfh      (OpenCOBOL) Use external SEQ/RAN file handler
  --with-cisam            (OpenCOBOL) Use CISAM for ISAM I/O
  --with-disam            (OpenCOBOL) Use DISAM for ISAM I/O
  --with-vbisam           (OpenCOBOL) Use VBISAM for ISAM I/O
  --with-index-extfh      (OpenCOBOL) Use external ISAM file handler
  --with-db1              (OpenCOBOL) use Berkeley DB 1.85 (libdb-1.85)
  --with-db               (OpenCOBOL) use Berkeley DB 3.0 or later (libdb)(default)
  --with-lfs64            (OpenCOBOL) use large file system for file I/O (default)
  --with-dl               (OpenCOBOL) use system dynamic loader (default)
  --with-patch-level      (OpenCOBOL) define a patch level (default 0)
  --with-varse         (OpenCOBOL) 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.3   Does OpenCOBOL have any other dependencies?

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

OpenCOBOL 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 pay royalty to Oracle Corporation. For more information about Oracle Berkeley DB dual licensing go to : Oracle / Embedded / Oracle Berkeley DB
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 OpenCOBOL compiler work?

OpenCOBOL 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

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

3.4.1   Example of OpenCOBOL stages

Documenting the output of the various stages of OpenCOBOL compilation.

3.4.2   Original source code;

$ cat hello.cob

000100* HELLO.COB OpenCOBOL 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 OpenCOBOL environment interacts with the native C facilities. OpenCOBOL 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 */
/* OpenCOBOL build date    Oct 01 2008 22:15:19 */
/* OpenCOBOL 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 */
/* OpenCOBOL build date    Oct 01 2008 22:15:19 */
/* OpenCOBOL 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

will do the same thing, but in this case, the extended Build is the same as the single Module build with -m. -b will build a dynamically loadable module that includes all of the entry points created from multiple command line inputs. It’s fun; you can mix .cob, .c, and -l libs and OpenCOBOL does the right thing glueing it all together. -b Build is suited to Programming In The Large and using cobcrun.

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.

This is important. cobc produces a Dynamic Shared Object by default. To create executables, you need to use -x.

$ ./hello
Hello World!

OpenCOBOL also supports features for multiple source, multiple language programming, detailed in the FAQ at Does OpenCOBOL support modules?.

3.4.13   sizes for hello on Fedora 16

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

3.5   What is cobc?

cobc is the OpenCOBOL compiler. It processes source code into object, library or executable code.

See What compiler options are supported? for more information.

3.6   What is cobcrun?

cobcrun is the OpenCOBOL driver program that allows the execution of programs stored in OpenCOBOL 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 OpenCOBOL development. It alleviates knowing which source file needs -x while encouraging proper modular programming, a mainstay of OpenCOBOL.

3.7   What is cob-config?

cob-config is a program that can be used to find 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 OpenCOBOL 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 OpenCOBOL compile time configuration files? for more details on this finely tuned control.

$ cobc -V
cobc (OpenCOBOL) 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.9   What dialects are supported by OpenCOBOL?

Using the std=<dialect> compiler option, OpenCOBOL can be configured to compile using specific historical COBOL compiler features and quirks.

Supported dialects include:

  • default
  • cobol85
  • cobol2002
  • ibm
  • mvs
  • mf
  • bs2000

For details on what options and switches are used to support these dialect compiles, see the config/ directory of your OpenCOBOL installation. For Debian GNU/Linux, that will be /usr/share/open-cobol/config/ if you used APT to install an OpenCOBOL package or /usr/local/share/open-cobol/config/ after a build from the source archive.

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

3.11   What are the OpenCOBOL compile time configuration files?

To assist in the support of the various existent COBOL compilers, OpenCOBOL 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: "OpenCOBOL"

# 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.12   Does OpenCOBOL work with make?

Absolutely. Very well.

A sample makefile

# OpenCOBOL rules

COBCWARN = -W

# create an executable
%: %.cob
      cobc $(COBCWARN) -x $^ -o $@

# create a dynamic module
%.so: %.cob
      cobc $(COBCWARN) -m $^ -o $@

# create a linkable object
%.o: %.cob
      cobc $(COBCWARN) -c $^ -o $@

# generate C code
%.c: %.cob
      cobc $(COBCWARN) -C $^

# generate assembly
%.s: %.cob
      cobc $(COBCWARN) -S $^

# generate intermediate suitable for cobxref
%.i: %.cob
      [ -d tmps ] || mkdir tmps
      cobc $(COBCWARN) --save-temps=tmps -c $^

# hack extension; create an executable; if errors, call vim in quickfix
%.q: %.cob
      cobc $(COBCWARN) -x $^ 2>errors.err || vi -q

# hack extension; make binary; capture warnings, call vim quickfix
%.qw: %.cob
      cobc $(COBCWARN) -x $^ 2>errors.err ; vi -q

# run ocdoc to get documentation
%.html: %.cob
      ./ocdoc $^ $*.rst $*.html $*.css

# run cobxref and get a cross reference listing  (leaves tmps dir around)
%.lst: %.cob
      [ -d tmps ] || mkdir tmps
      cobc $(COBCWARN) --save-temps=tmps -c $^ -o tmps/$*.o && ~/writing/add1/tools/cobxref/cobxref tmps/$*.i

# tectonics for occurlrefresh
occurlrefresh: occurl.c occurlsym.cpy occurlrefresh.cbl
      cobc -c -Wall occurl.c
      cobc -x -lcurl occurlrefresh.cbl occurl.o

And now to compile a small program called program.cob, just use

$ make program       # for executables
$ make program.o     # for object files
$ make program.so    # for shared library
$ make program.q     # create an executable and call vi in quickfix mode

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 timestamp of the binary.

See Tectonics for another word to describe building code.

3.13   Do you have a reasonable source code skeleton for OpenCOBOL?

Maybe. Style is a very personal developer choice. OpenCOBOL pays homage to this freedom of choice.

Here is the FIXED form header that this author uses. It includes ocdoc lines.

OCOBOL >>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 .
      *><*
      *><* 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 templates that can cut and pasted.

Fixed form in lowercase

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

Fixed form in UPPERCASE

OCOBOL >>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 OCOBOL “sequence number” can safely be removed. It is there to ensure proper alignment in the browser.

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

Note

There are tricks to ensure that FIXED FORMAT source code can be compiled in a FREE FORMAT mode. That includes using free form end of line comments, no sequence numbers, free form DEBUG line directives with the >>D starting in column 5 (so the D ends up in column 7).

3.14   Can OpenCOBOL 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.

OCOBOL >>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.15   How do you print to printers with OpenCOBOL?

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

OCOBOL 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 OpenCOBOL?

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

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

OpenCOBOL 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.clb was placed into the tree, the output includes the call graphs that exercise some of the OpenCOBOL runtime library. This application level documentation is world class.

Regarding the above “sort of”. This was a near effortless use of Doxygen. OpenCOBOL 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 OpenCOBOL?

LD_RUN_PATH can be a saving grace for developers that want to build OpenCOBOL 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 OpenCOBOL 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 OpenCOBOL. 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 runtime.

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 OpenCOBOL for CGI?, you can now build up a complete web side solution using OpenCOBOL with little worry about being stuck on link library depencencies 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 OpenCOBOL?

The sources for the OpenCOBOL 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 OpenCOBOL? for the first steps with ./configure.

3.19.2   Out of tree builds

Next up, OpenCOBOL 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".

3.19.3   Autotest options

By developing the OpenCOBOL 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 OpenCOBOL program?

This is actually a frequently asked question, and it usually has the same answer.

OpenCOBOL 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 END-DISPLAY
goback.

will cause the Curses package to initialize a secondary buffer, display the Hello string, then immediately restore the primary 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 an unused variable which will cause a wait for carriage return.
  • or even better, dump the secondary buffer from all Curses screen handling.

The last option is discussed here.

3.20.1   SMCUP and RMCUP

https://blogs.oracle.com/samf/entry/smcup_rmcup_hate is a great article that discusses, and sledge-hammer fixes, the curses init screen clearing issue, leaving output on the stdout terminal, not an alternate screen.

First to find out the actual terminal capabilites, (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 to worry about. By default, infocmp reads local user files, but this change can also effect the entire system.

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.

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.

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, will move on and create a local compiled file if it can’t.

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 end-display
display "Goodbye, smcup/rmcup" at 0313 end-display
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]$

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

4   Reserved Words

COBOL Reserved Words

4.1   What are the OpenCOBOL RESERVED WORDS?

COBOL is a reserved word rich language. The OpenCOBOL compiler recognizes:

Reserved Words

514 words in OC 1.1, 136 of which are marked not yet implemented. 378 functional reserved words, as of August 2008.

4.1.1   ACCEPT

Makes data available from the keyboard or operating system to named data items. OpenCOBOL 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.

ACCEPT variable FROM CONSOLE.

ACCEPT variable FROM ENVIRONMENT "path".
ACCEPT variable FROM COMMAND LINE.

ACCEPT variable AT 0101.
ACCEPT screen-variable.

ACCEPT today FROM DATE.
ACCEPT today FROM DATE YYYYMMDD.

4.1.2   ACCESS

Defines a file’s access mode. One of DYNAMIC, RANDOM, or SEQUENTIAL.

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.

ADD 1 TO cobol GIVING OpenCOBOL END-ADD.

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

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 ADDRESS OF working-var

4.1.6   ADVANCING

Programmer control of newline output and paging.

DISPLAY "Legend: " WITH NO ADVANCING END-DISPLAY.
WRITE printrecord AFTER ADVANCING PAGE END-WRITE.

4.1.7   AFTER

Nested PERFORM clause and can influence when loop conditional testing occurs.

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

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.

4.1.10   ALLOCATE

Allocates actual working storage for a BASED element.

ALLOCATE based-var INITIALIZED RETURNING pointer-var.

4.1.11   ALPHABET

* Set up for a mixed case SORT COLLATING SEQUENCE IS
 CONFIGURATION SECTION.
 SPECIAL-NAMES.
     ALPHABET name IS "AaBbCcDdEe..".

4.1.12   ALPHABETIC

One of the OpenCOBOL data class (category) tests.

IF variable IS ALPHABETIC
    DISPLAY "alphabetic" END-DISPLAY
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 OpenCOBOL data class (category) tests.

IF variable IS ALPHABETIC-LOWER
    DISPLAY "alphabetic-lower" END-DISPLAY
END-IF

4.1.14   ALPHABETIC-UPPER

One of the OpenCOBOL 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" END-DISPLAY
ELSE
    DISPLAY "false A-Z, something else in here" END-DISPLAY
END-IF

4.1.15   ALPHANUMERIC

INITIALIZE data-record REPLACING ALPHANUMERIC BY literal-value

4.1.16   ALPHANUMERIC-EDITED

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-test
    WHEN "A"      ALSO 1 THRU 5     PERFORM first-case
    WHEN "A"      ALSO 6            PERFORM second-case
    WHEN "A"      ALSO 7 THRU 9     PERFORM third-case
    WHEN OTHER                      PERFORM invalid-case
END-EVALUATE

4.1.18   ALTER

Obsolete and once unsupported verb that modifies the jump target for GO TO statements.

Yeah, just don’t. Unless you are writing a state machine engine, maybe. ALTER should rarely be used in COBOL applications.

Rumour is, 1.1 may support this verb, to increase support for legacy code, and NOT as homage to a good idea. But to be honest, I do look forward to seeing the first OpenCOBOL Flying Spaghetti Monster for the giggles of righteous indignation.

Reality is, 2.0 does support ALTER. NIST Test Suite passes over 9,700 tests, up from just under 9,100 with 1.1.

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

COBOL rules of precedence are; NOT, AND, OR.

IF field = "A" AND num = 3
    DISPLAY "got 3" END-DISPLAY
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.

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 insentive 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 END-ACCEPT

DISPLAY 2 UPON ARGUMENT-NUMBER END-DISPLAY
ACCEPT indexed-command-line-argument FROM ARGUMENT-VALUE END-ACCEPT

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

PROGRAM-ID. program-name AS literal.

4.1.30   ASCENDING

COBOL table suport.

01 CLUBTABLE.
   05 MEMBER-DATA OCCURS 1 TO 6000000000 TIMES
        DEPENDING ON PEOPLE
        ASCENDING KEY IS HOURS-DONATED.

4.1.31   ASSIGN

Assign a name to a file or other external resource.

SELECT input-file
ASSIGN TO "filename.ext"

The actual filename used is dependent on a configuration setting. Under default configuration settings, filename-mapping is set to yes.

See What are the OpenCOBOL 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 enviroment variables before using a literal as the filename.

  • DD_DATAFILE
  • dd_DATAFILE
  • DATAFILE
  • and finally “DATAFILE”

where DATAFILE is the name used in

ASSIGN TO name

and can be any valid COBOL identifier, or string leading to a valid operating system filename.

4.1.32   AT

Controls position of ACCEPT and DISPLAY screen oriented verbs.

*> Display at line 1, column 4 <*
 DISPLAY "Name:" AT 0104 END-DISPLAY
*> Accept starting at line 1, column 10 for length of field <*
 ACCEPT name-var AT 0110 END-ACCEPT

4.1.33   ATTRIBUTE

Not yet implemented, but when it is, it will allow

SET screen-name ATTRIBUTE BLINK OFF

4.1.34   AUTO

Automatic cursor flow to next field in screen section.

4.1.36   AUTOMATIC

LOCK MODE IS AUTOMATIC. See MANUAL and EXCLUSIVE for more LOCK options.

4.1.38   B-AND

Not yet implemented BIT field operation. See What STOCK CALL LIBRARY does OpenCOBOL offer? CBL_AND for alternatives allowing bitwise operations.

4.1.39   B-NOT

Not yet implemented BIT field operation. See What STOCK CALL LIBRARY does OpenCOBOL offer? CBL_NOT for alternatives allowing bitwise operations.

4.1.40   B-OR

Not yet implemented BIT field operation. See What STOCK CALL LIBRARY does OpenCOBOL offer? CBL_OR for alternatives allowing bitwise operations.

For example:

OCOBOL >>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 end-display

       goback.
       end program bits.

giving:

$ cobc -x bits.cob
$ ./bits
002 006 1 +0000000000

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

Not yet implemented BIT field operation. See What STOCK CALL LIBRARY does OpenCOBOL offer? CBL_XOR for alternatives allowing bitwise operations.

4.1.42   BACKGROUND-COLOR

05 BLANK SCREEN BACKGROUND-COLOR 7 FOREGROUND-COLOR 0.

4.1.43   BASED

01 based-var PIC X(80) BASED.

A sample posted by [human]

OCOBOL*-----------------------------------------------------------------
       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)
           end-display
           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)
              end-display
           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.44   BEEP

Ring the terminal bell during DISPLAY output. Alias for BELL

DISPLAY "Beeeeep" LINE 3 COLUMN 1 WITH BEEP END-DISPLAY.

4.1.45   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 not currently (February 2013) supported, in the declaratives for REPORT SECTION control.

USE BEFORE REPORTING
 ...

4.1.46   BELL

Ring the terminal bell during DISPLAY output. Alias for BEEP

DISPLAY "Beeeeep" LINE 3 COLUMN 1 WITH BELL END-DISPLAY.

4.1.47   BINARY

01 result PIC S9(8) USAGE BINARY

4.1.48   BINARY-C-LONG

With OpenCOBOL’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.49   BINARY-CHAR

Defines an 8 bit usage item.

4.1.50   BINARY-DOUBLE

Defines a 64 bit usage item.

4.1.51   BINARY-LONG

32 bit native USAGE modifier. Equivalent to S9(8).

4.1.52   BINARY-SHORT

16 bit native USAGE. Equivalent to S9(5).

4.1.53   BIT

Not yet implemented. See What STOCK CALL LIBRARY does OpenCOBOL offer? for alternatives allowing bitwise operations.

4.1.54   BLANK

05 BLANK SCREEN BACKGROUND-COLOR 7 FOREGROUND-COLOR 0.

4.1.56   BLOCK

FD file-name
  BLOCK CONTAINS 1 TO n RECORDS

4.1.57   BOOLEAN

As yet unsupported modifier.

4.1.58   BOTTOM

A LINAGE setting.

FD  mini-report
      linage is 16 lines
          with footing at 15
          lines at top 2
          lines at bottom 2.

4.1.59   BY

PERFORM the-procedure
    VARYING step-counter FROM 1 BY step-size
    UNTIL step-counter > counter-limit

4.1.60   BYTE-LENGTH

Human inscisors average about 16mm.

More to the point, the BYTE-LENGTH returns the length, in bytes, of a data item. See FUNCTION BYTE-LENGTH

4.1.61   CALL

The OpenCOBOL CALL verb accepts literal or identifier stored names when resolving the transfer address. The USING phrase allows argument passing and OpenCOBOL includes internal rules for the data representation of the call stack entities that depend on the COBOL PICTURE and USAGE clauses. Return values are captured with RETURNING identifier. See What STOCK CALL LIBRARY does OpenCOBOL offer?.

For more information see http://www.opencobol.org/modules/bwiki/index.php?cmd=read&page=UserManual%2F2_3#content_1_0

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 CALLs, the argument from COBOL should usually by 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.

OCOBOL*>>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 end-display

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

4.1.62   CANCEL

Virtual cancel of a module is supported. Physical cancel support is on the development schedule.

4.1.63   CD

A control clause of the as yet unsupported COMMUNICATION DIVISION.

4.1.64   CENTER

An as yet unsupported keyword.

4.1.65   CF

Shortform for CONTROL FOOTING, a clause used in REPORT SECTION.

4.1.66   CH

Shortform for CONTROL HEADING, a clause used in PAGE descriptors in the REPORT SECTION.

4.1.67   CHAIN

Invokes a subprogram, with no return of control implied. The chained program unit virtually becomes the main program within the run unit.

4.1.68   CHAINING

Passes procedure division data through WORKING-STORAGE and can be used for shell command line arguments as well, as in CALL “myprog” USING string END-CALL.

from opencobol.org by human

WORKING-STORAGE SECTION.
    01 cmd-argument.
      02 some-text pic x(256).

procedure division Chaining cmd-argument.

display 'You wrote:'
        '>"' function trim(some-text) '"'
        'from shell command line'
end-display

4.1.69   CHARACTER

PADDING CHARACTER IS

A soon to be obsolete feature.

4.1.70   CHARACTERS

A multi use keyword.

Used in SPECIAL-NAMES

OCOBOL >>SOURCE FORMAT IS FIXED
      *> ***************************************************************
      *> Author:    Brian Tiffin
      *> Date:      20101031
      *> Purpose:   Try out SYMBOLIC CHARACTERS
      *> Tectonics: cobc -x figurative.cob
      *> Rave:      OpenCOBOL 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"
       end-display

       move a-comma to lots-of-commas
       display "MOVE a-comma : " lots-of-commas end-display

       move CMA to lots-of-commas
       display "MOVE symbolic: " lots-of-commas end-display

       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 tal FOR CHARACTERS

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.

4.1.71   CLASS

Used to create alphabets in SPECIAL-NAMES.

ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES.
CLASS octals IS '0' THRU '7'.

...

PROCEDURE DIVISION.
IF user-value IS NOT octals
    DISPLAY "Sorry, not a valid octal number" END-DISPLAY
ELSE
    DISPLAY user-value END-DISPLAY
END-IF

4.1.72   CLASS-ID

An as yet unsupported Object COBOL class identifier clause.

4.1.73   CLASSIFICATION

An as yet unsupported source code internationalization clause.

4.1.74   CLOSE

Close an open file. OpenCOBOL will implicitly close all open resources at termination of a run unit and will display a warning message stating so, and the danger of potentially unsafe termination.

CLOSE input-file

4.1.75   CODE

A syntactically recognized, but as yet unsupported clause of a report descriptor, RD.

4.1.76   CODE-SET

An as yet unsupported data internationalization clause.

4.1.78   COLLATING

Allows definition within a program unit of a character set.

OBJECT-COMPUTER. name.
  PROGRAM COLLATING SEQUENCE IS alphabet-1.

4.1.80   COLUMN

  1. A recognized but unsupported REPORT SECTION RD descriptor clause.
  2. Also used for positional DISPLAY and ACCEPT, which implicitly uses SCREEN SECTION style ncurses screen IO.
DISPLAY var-1 LINE 1 COLUMN 23 END-DISPLAY

4.1.81   COLUMNS

A recognized but as yet unsupported RD clause.

4.1.82   COMMA

A SPECIAL-NAMES clause supporting commas in numeric values versus the default period decimal point. COBOL was way ahead of the internationization 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.83   COMMAND-LINE

Provides access to command line arguments.

ACCEPT the-args FROM COMMAND-LINE END-ACCEPT

4.1.84   COMMIT

Flushes ALL current locks, synching file I/O buffers. OpenCOBOL supports safe transactional processing with ROLLBACK capabilities. Assuming the ISAM handler configured when building the compiler can support LOCK_

4.1.85   COMMON

PROGRAM-ID. CBL_OC_PROGRAM IS COMMON PROGRAM.

Ensures a nested sub-program is also available to other nested sub-programs with a program unit heirarchy.

4.1.86   COMMUNICATION

currently (February 2013) unsupported DIVISION, but see Does OpenCOBOL support Message Queues? for an alternative.

4.1.94   COMPUTATIONAL

Implementors choice; OpenCOBOL is a big-endian default. With most Intel personal computers and operating systems like GNU/Linux, COMPUTATIONAL-5 will run faster.

4.1.95   COMPUTATIONAL-1

Single precision float. Equivalent to FLOAT-SHORT.

4.1.96   COMPUTATIONAL-2

Double precision float. Equivalent to FLOAT-LONG.

4.1.97   COMPUTATIONAL-3

Equivalent to PACKED DECIMAL. Packed decimal is two digits per byte, always sign extended and influenced by a .conf setting binary-size COMPUTATIONAL-6 is UNSIGNED PACKED.

4.1.98   COMPUTATIONAL-4

Equivalent to BINARY.

4.1.100   COMPUTATIONAL-6

Unsigned packed decimal form, see COMPUTATIONAL-3.

4.1.102   COMPUTE

Computational arithmetic.

COMPUTE circular-area = radius ** 2 * FUNCTION PI END-COMPUTE

OpenCOBOL 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

OCOBOL*> ***************************************************************
       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, OpenCOBOL will complain.

$ cobc -x computing.cob
computing.cob:18: Error: 'var-1' is not defined

whew, saved!

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

OpenCOBOL will (properly, according to standard) compile this as three times var-1. Not saved, if you meant 3 times var minus 1.

OpenCOBOL programmers are strongly encouraged to use full spacing inside COMPUTE statements.

OCOBOL*> ***************************************************************
       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" end-display
           not on size error
               display "All good, answer is trustworthy" end-display
       end-compute

       goback.
       end program computing.

COMPUTE supports ON SIZE ERROR, NOT ON SIZE ERROR imperatives for safety, and the ROUNDED modifier for bankers.

4.1.103   CONDITION

As yet unsupported USE AFTER EXCEPTION CONDITION clause.

4.1.105   CONSTANT

An extension allowing constant definitions

01 enumerated-value CONSTANT AS 500.

4.1.106   CONTAINS

An FD clause:

FD a-file RECORD CONTAINS 80 CHARACTERS.

4.1.107   CONTENT

A CALL clause that controls how arguments are passed and expected.

CALL "subprog" USING BY CONTENT alpha-var.

alpha-var will not be modifieable by subprog as a copy is passed.

See REFERENCE and VALUE for the other supported CALL argument control.

4.1.108   CONTINUE

A placeholder, no operation verb.

if action-flag = "C" or "R" or "U" or "D"
    continue
else
    display "invalid action-code" end-display
end-if

4.1.109   CONTROL

As yet unsupported REPORT SECTION clause for setting control break data fields.

4.1.110   CONTROLS

As yet unsupported REPORT SECTION clause for setting control break data fields.

4.1.111   CONVERTING

A clause of the INSPECT verb.

INSPECT X CONVERTING "012345678" TO "999999999".

4.1.112   COPY

The COBOL include pre-processor verb. Also see REPLACE and Does OpenCOBOL support COPY includes?.

4.1.114   CORRESPONDING

Move 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
end-display

4.1.115   COUNT

Sets the count of characters set in an UNSTRING substring.

From the OpenCOBOL 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.116   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 OpenCOBOL 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.117   CURRENCY

SPECIAL-NAMES.
    CURRENCY SIGN IS literal-1.

Default currency sign is the dollar sign “$”.

4.1.118   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.119   CYCLE

A clause that causes EXIT PERFORM to return to the top of a loop. See FOREVER for an example.

4.1.120   DATA

A magical DIVISION. One of COBOL’s major strength is the rules surrounding the DATA DIVISION and pictorial record definitions.

4.1.121   DATA-POINTER

An as yet unsupported Object COBOL feature.

4.1.122   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 end-display

 goback.
 end program dates.
./dates
110701 20110701

4.1.123   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
OCOBOL >>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 end-display

       goback.
       end program days.
$ make days
cobc -W -x days.cob -o days
$ ./days
11182 2011182

4.1.124   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.125   DE

Report Writer shortcut for DETAIL. Recognized, but not yet implemented. 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.126   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-DISPLAY
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.127   DECIMAL-POINT

Allows internationization for number formatting. In particular

IDENTIFICATION DIVISION.
PROGRAM-ID. 'MEMALL'.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES. DECIMAL-POINT IS COMMA.

will cause OpenCOBOL to interpret numeric literals along the lines of 123,45 as one hundred twenty three and forty five one hundreths.

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.128   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 end-display.
.
helpful-debug section.
    use for debugging on main-file.
help-me.
    display "Just touched " main-file end-display.
.
end declaratives.

4.1.129   DEFAULT

A multi-use clause used in

  • CALL ... SIZE IS DEFAULT
  • ENTRY ... SIZE IS DEFAULT
  • INITIALIZE ... WITH ... THEN TO DEFAULT

4.1.130   DELETE

Allows removal of records from RELATIVE and INDEXED files.

DELETE filename-1 RECORD
  INVALID KEY
    DISPLAY "no delete" END-DISPLAY
  NOT INVALID KEY
    DISPLAY "record removed" END-DISPLAY
END-DELETE

4.1.130.1   OC 2.0

Allows file deletes.

DELETE FILE
    filename-1 filename-2 filename-3
END-DELETE

4.1.131   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.132   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.133   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.134   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.135   DESTINATION

Currently unsupported data descriptor. Part of VALIDATE.

4.1.136   DETAIL

A recognized but currently unsupported report descriptor detail line control clause.

4.1.137   DISABLE

An unsupported COMMUNICATION SECTION control verb.

4.1.138   DISK

A SELECT devicename phrase.

ASSIGN TO DISK USING dataname

Alternative spelling of DISC is allowed.

4.1.139   DISPLAY

A general purpose output verb.

  • 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 enviroment 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" END-DISPLAY

DISPLAY "1" 23 "4" END-DISPLAY

The setting of environment variables does not influence the owning process shell.

DISPLAY "ENVNAME" UPON ENVIRONMENT-NAME END-DISPLAY
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

4.1.140   DIVIDE

Highly precise arthimetic. Supports various forms:

  • DIVIDE INTO
  • DIVIDE INTO GIVING
  • DIVIDE BY GIVING
  • DIVIDE INTO REMAINDER
  • DIVIDE BY 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 20xx draft 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.141   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”.

OpenCOBOL 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 OpenCOBOL program? for an example.

4.1.142   DOWN

Allows decrement of an index control or pointer variable.

SET ind-1 DOWN BY 2

Also used for SCREEN SECTION scroll control.

SCROLL DOWN 5 LINES

4.1.143   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.144   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.145   EBCDIC

Extended Binary Coded Decimal Interchange Code.

A character encoding common to mainframe systems, therefore COBOL, therefore OpenCOBOL. Different than ASCII and OpenCOBOL supports both through efficient mappings. See http://en.wikipedia.org/wiki/EBCDIC for more info.

ASCII to EBCDIC conversion the OpenCOBOL way

SPECIAL-NAMES.
ALPHABET ALPHA IS NATIVE.
ALPHABET BETA IS EBCDIC.

PROCEDURE DIVISION.
INSPECT variable CONVERTING ALPHA TO BETA

4.1.146   EC

An unsupported shortform for USE AFTER EXCEPTION CONDITION

4.1.147   EGI

An unsupported COMMUNICATION SECTION word.

4.1.148   ELSE

Alternate conditional branch point.

IF AGE IS ZERO
   DISPLAY "Cigar time" END-DISPLAY
ELSE
   DISPLAY "What is it with kids anyway?" END-DISPLAY
END-IF

For multi branch conditionals, see EVALUATE.

4.1.149   EMI

An unsupported COMMUNICATION SECTION word.

4.1.150   ENABLE

An unsupported COMMUNICATION SECTION control verb.

4.1.151   END

Ends things. Programs, declaratives, functions.

4.1.152   END-ACCEPT

Explicit terminator for ACCEPT.

4.1.153   END-ADD

Explicit terminator for ADD.

4.1.154   END-CALL

Explicit terminator for CALL.

4.1.155   END-COMPUTE

Explicit terminator for COMPUTE.

4.1.156   END-DELETE

Explicit terminator for DELETE.

4.1.157   END-DISPLAY

Explicit terminator for DISPLAY.

4.1.158   END-DIVIDE

Explicit terminator for DIVIDE.

4.1.159   END-EVALUATE

Explicit terminator for EVALUATE.

4.1.160   END-IF

Explicit terminator for IF.

4.1.161   END-MULTIPLY

Explicit terminator for MULTIPLY.

4.1.162   END-OF-PAGE

A LINAGE phrase used by WRITE controlling end of page imperative clause.

4.1.163   END-PERFORM

Explicit terminator for PERFORM.

4.1.164   END-READ

Explicit terminator for READ.

4.1.165   END-RECEIVE

Explicit terminator for RECEIVE.

4.1.166   END-RETURN

Explicit terminator for RETURN.

4.1.167   END-REWRITE

Explicit terminator for REWRITE.

4.1.169   END-START

Explicit terminator for START.

4.1.170   END-STRING

Explicit terminator for STRING.

4.1.171   END-SUBTRACT

Explicit terminator for SUBTRACT.

4.1.172   END-UNSTRING

Explicit terminator for UNSTRING.

4.1.173   END-WRITE

Explicit terminator for WRITE.

4.1.174   ENTRY

Always for CALL entry points without being fully specified sub-programs. Great for defining callbacks required by many GUI frameworks.

See Does OpenCOBOL support the GIMP ToolKit, GTK+? for an example.

4.1.175   ENTRY-CONVENTION

An as yet unsupported clause.

4.1.176   ENVIRONMENT

Divisional name. And allows access to operating system environment variables. OpenCOBOL supports

within the ENVIROMENT 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.177   ENVIRONMENT-NAME

Provides access to the running process environment variables.

4.1.178   ENVIRONMENT-VALUE

Provides access to the running process environment variables.

4.1.179   EO

An unsupported shortform for USE AFTER EXCEPTION OBJECT

4.1.180   EOL

ERASE to End Of Line.

4.1.181   EOP

LINAGE clause shortform for END-OF-PAGE.

4.1.182   EOS

ERASE to End Of Screen.

4.1.183   EQUAL

Conditional expression to compare two data items for equality.

4.1.184   EQUALS

Conditional expression to compare two data items for equality.

4.1.185   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.186   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.187   ESCAPE

Programmer access to escape key value during ACCEPT.

ACCEPT identifier FROM ESCAPE KEY END-ACCEPT

Data type is 9(4).

4.1.188   ESI

Unsupported COMMUNICATION SECTION control.

4.1.189   EVALUATE

A very powerful and concise selection construct.

EVALUATE a ALSO b ALSO TRUE
    WHEN 1 ALSO 1 THRU 9 ALSO c EQUAL 1 PERFORM all-life
    WHEN 2 ALSO 1 THRU 9 ALSO c EQUAL 2 PERFORM life
    WHEN 3 THRU 9 ALSO 1 ALSO c EQUAL 9 PERFORM disability
    WHEN OTHER PERFORM invalid
END-EVALUATE

4.1.190   EXCEPTION

Allow detection of CALL problem.

CALL "CBL_OC_DUMP" ON EXCEPTION CONTINUE END-CALL

4.1.191   EXCEPTION-OBJECT

Unsupport object COBOL data item reference.

4.1.192   EXCLUSIVE

Mode control for file locks.

4.1.193   EXIT

OpenCOBOL supports

Controls flow of the program. EXIT PERFORM CYCLE causes an inline perform to return control to the VARYING, UNTIL or TIMES clause, testing the conditional to see if another cycle is required. EXIT PERFORM without the CYCLE option causes flow to continue passed the end of the current PERFORM loop.

4.1.194   EXPANDS

Unsupported COMMUNICATION SECTION control.

4.1.195   EXTEND

Open a resource in an append mode.

4.1.196   EXTERNAL

Clause to specify external data item, file connection and program unit.

77 shared-var PIC S9(4) IS EXTERNAL AS 'shared_var'.

4.1.197   FACTORY

An unsupported object COBOL keyword.

4.1.198   FALSE

Logical false and conditional set condition.

01 record-1      pic 9.
   88 conditional-1 values 1,2,3 when set to false is 0.

set conditional-1 to true
display record-1 end-display

set conditional-1 to false
display record-1 end-display

if conditional-1
    display "BAD" end-display
end-if

Runs as:

$ ./conditionals
1
0

Also used in EVALUATE, inverting the normal sense of WHEN

evaluate false
    when 1 equal 1
        display "Not displayed, as 1 equal 1 is true" end-display
    when 1 equal 2
        display "This displays because 1 equal 2 is false" end-display
    when other
        display "the truest case, nothing is false" end-display
end-evaluate

4.1.199   FD

The record side of the COBOL file system. The File Descriptor. COBOL provides lots of control over file access. FD is part of that engine.

Sort files use SD

Some FD phrases are old, and their uses have been overtaken by features of modern operating systems.

  • BLOCK CONTAINS
  • RECORDING MODE IS

Others are pretty cool. LINAGE is one example. FD supports a mini report writer feature. Control over lines per page, heaVer, footer and a line counter, LINAGE IS, that is implicitly maintained by OpenCOBOL during file writes. These files are usually reports, but they don’t have to be, LINAGE can be used for a simple step counter when you’d like progress displays of file updates.

Other recognized file descriptions include:

  • RECORD IS VARYING IN SIZE FROM 1 TO 999999999 DEPENDING ON size-variable Record sizes need to fit in PIC 9(9), just shy of a thousand million.
  • CODE-SET IS alphabet-name
  • DATA RECORD IS data-name
  • LABEL RECORDS ARE STANDARD (or OMITTED)
  • RECORD CONTAINS 132 CHARACTERS
FD filename-sample
   RECORD IS VARYING IN SIZE FROM 1 TO 32768 CHARACTERS
     DEPENDING ON record-size-sample.

4.1.200   FILE

FILE is another multi use COBOL word.

  • A SECTION of the DATA DIVISION.

The FILE section holds file description paragraphs and buffer layouts.

data division.
FILE section.
fd cobol-file-selector.
01 cobol-io-buffer        pic x(132).
  • a context word for setting name for FILE STATUS fields in FILE-CONTROL paragraphs.

Some programmers don’t like seeing COBOL code that does not verify and test FILE STATUS, so you should. See ISAM for the numeric codes supported.

environment division.
input-output section.
file-control.
   select optional data-file assign to file-name
       organization is line sequential
       FILE STATUS is data-file-status.
   select mini-report assign to "mini-report".
  • a context word as part of the PROCEDURE DIVISION declarative statements allowing for out-of-band exception handling for file access.

Exception handling with declaratives can be powerful, but some programmers find the out of band nature of where the source code that caused a problem compared to where the error handler is, distasteful.

procedure division.
declaratives.

error-handling section.
    USE AFTER EXCEPTION FILE filename-maybe.
error-handler.
    display "Exception on filename" end-display
.
end declaratives.

Support for USE AFTER EXCEPTION FILE is a work in progress. Using DECLARATIVES forces use of section names in the PROCEDURE DIVISION.

  • a context word as part of DELETE FILE filenames.
DELETE FILE file-selector-1 file-selector-2

DELETE FILE is supported in OpenCOBOL 2.0.

4.1.201   FILE-CONTROL

Files. The paragraph in the INPUT-OUTPUT section, in the ENVIRONMENT division. It’s verbose, a little voodooey, and worth it.

environment division.
input-output section.
FILE-CONTROL.
  select optional data-file assign to file-name
      organization is line sequential
      file status is data-file-status.

  select mini-report assign to "mini-report".

4.1.202   FILE-ID

File naming clause. Assigned name may be device, FD clause specifies value of the file identifier.

VALUE OF FILE-ID IS file-ids in summary-array

more specifically

environment division.
input-output section.
file-control.
    select cobol-file-selector
    assign to disk
    organization            indexed
    access mode             dynamic
    record key              fd-key-field
    file status             file-status-field.

data division.
file section.
fd cobol-file-selector label record standard
    VALUE OF FILE-ID is "actual-filename.dat".

An alternative, and likely more common, method is to set the actual filename (or the enviroment variable that references the actual filename) in the ASSIGN clause. OpenCOBOL has a configuration setting to control how the actual filenames are mapped, see ASSIGN. VALUE OF FILE-ID is not ISO standard COBOL.

4.1.203   FILLER

Data division clause, for unnamed data allocations; filler, if you will.

01 the-record.
   05 first-field  pic x(10).
   05 filler       pic x(35) value "this space intentionally left blank".
   04 third-field  pic x(10).

FILLER is an optional word, and this code snippet is equivalent.

01 the-record.
    05 first-field  pic x(10).
    05              pic x(35) value "this space intentionally left blank".
    05 third-field  pic x(10).

Personal preference of this author is to explicitly type FILLER.

4.1.204   FINAL

Final. A recognized but currently not supported Report Writer feature.

4.1.205   FIRST

First. A recognized but currently not supported Report Writer feature.

4.1.206   FLOAT-EXTENDED

OpenCOBOL recognizes but does not yet support FLOAT-EXTENDED and will abend a compile.

4.1.207   FLOAT-LONG

OpenCOBOL supports floating point long.

identification division.
program-id. threes.

data division.
working-storage section.
01 fshort usage float-short.
01 flong  usage float-long.
01 fpic   pic   9v9(35).

procedure division.
compute fshort = 1 / 3 end-compute
display "as short " fshort end-display
compute flong = 1 / 3 end-compute
display "as long  " flong end-display
compute fpic = 1 / 6 end-compute
display "as pic   " fpic end-display
compute fpic rounded = 1 / 6 end-compute
display "rounded  " fpic end-display
goback.

end program threes.

displays:

$ ./threes
as short 0.333333343267440796
as long  0.333333333333333315
as pic   0.16666666666666666666666666666666666
rounded  0.16666666666666666666666666666666667

4.1.208   FLOAT-SHORT

OpenCOBOL supports short floating point.

4.1.209   FOOTING

A well supported LINAGE clause.

4.1.210   FOR

Recognized but unsupported Report Writer clause.

4.1.212   FOREVER

Provides for infinite loops. Use EXIT PERFORM or EXIT PERFORM CYCLE to control program flow.

identification division.
program-id. foreverloop.

data division.
working-storage section.
01 cobol   pic 9 value 0.
01 c       pic 9 value 1.
01 fortran pic 9 value 2.

procedure division.

perform forever
    add 1 to cobol
    display "cobol at " cobol end-display

    if cobol greater than fortran
        exit perform
    end-if

    if cobol greater than c
        exit perform cycle
    end-if

    display "cobol still creeping up on c" end-display
end-perform

display "cobol surpassed c and fortran" end-display

goback.
end program foreverloop.

Which produces:

$ cobc -free -x foreverloop.cob
$ ./foreverloop
cobol at 1
cobol still creeping up on c
cobol at 2
cobol at 3
cobol surpassed c and fortran

I asked on opencobol.org for some input, and an interesting conversation ensued. I’ve included the forum thread archive, nearly in its entirety, to give a sense of various programmer styles and group thought processing. See Performing FOREVER?.

4.1.213   FORMAT

Source format directive.

123456 >>SOURCE FORMAT IS FIXED

4.1.214   FREE

Properly cleans up ALLOCATE alloted memory, and source format directive.

>>SOURCE FORMAT IS FREE

 01 var PIC X(1024) BASED.

 ALLOCATE var
 CALL "buffer-thing" USING BY REFERENCE var END-CALL
 MOVE var TO working-store
 FREE var

4.1.215   FROM

ACCEPT var FROM ENVIRONMENT "path"
    ON EXCEPTION
        DISPLAY "No path" END-DISPLAY
    NOT ON EXCEPTION
        DISPLAY var END-DISPLAY
END-ACCEPT

4.1.216   FULL

A screen section screen item control operator, requesting the normal terminator be ignored until the field is completely full or completely empty.

4.1.217   FUNCTION

Allows use of the many OpenCOBOL supported intrinsic functions.

DISPLAY FUNCTION TRIM("   trim off leading spaces" LEADING) END-DISPLAY.

See Does OpenCOBOL implement any Intrinsic FUNCTIONs? for details.

4.1.218   FUNCTION-ID

Not yet implemented, but it will allow for user defined FUNCTION.

4.1.219   GENERATE

Not yet implemented beyond simple parsing REPORT writer feature.

4.1.220   GET

Unsupported.

4.1.221   GIVING

Destination control for computations, and return value clause.

ADD 1 TO cobol GIVING OpenCOBOL.

4.1.222   GLOBAL

A global name is accessible to all contained programs.

4.1.223   GO

GO TO is your friend. Edsger was wrong. Transfer control to a named paragraph or section. See ALTER for details of monster goto power.

4.1.224   GOBACK

A return. This will work correctly for all cases. A return to the operating system or a return to a called program.

GOBACK.

4.1.225   GREATER

COBOL conditional expression, IF A GREATER THAN B, See LESS

4.1.226   GROUP

Recognized but unsupported Report Writer clauses.

4.1.227   GROUP-USAGE

An unsupported BIT clause.

4.1.228   HEADING

Recognized but unsupported Report Writer clauses.

4.1.229   HIGH-VALUE

A figurative ALPHABETIC constant, being the highest character value in the COLLATING sequence. It’s invalid to MOVE HIGH-VALUE to a NUMERIC field.

4.1.231   HIGHLIGHT

Screen control for field intensity.

4.1.232   I-O

An OPEN mode allowing for both read and write.

4.1.233   I-O-CONTROL

A paragraph in the INPUT-OUTPUT section, allowing sharing memory areas for different files.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
I-O-CONTROL.
    SAME RECORD AREA FOR filename-1 filename-2.

4.1.235   IDENTIFICATION

The initial division for OpenCOBOL programs.

IDENTIFICATION DIVISION.
PROGRAM-ID. sample.

Many historical paragraphs from the IDENTIFICATION DIVISION have been deemed obsolete. OpenCOBOL will treat these as comment paragraphs. Including

  • AUTHOR
  • DATE-WRITTEN
  • DATE-MODIFIED
  • DATE-COMPILED
  • INSTALLATION
  • REMARKS
  • SECURITY

4.1.236   IF

Conditional branching. In COBOL, conditionals are quite powerful and there are many conditional expressions allowed with concise shortcuts.

IF A = 1 OR 2
    MOVE 1 TO B
END-IF

4.1.237   IGNORING

READ filename-1 INTO identifer-1 IGNORING LOCK END-READ

4.1.238   IMPLEMENTS

Unsupported Object COBOL expression.

4.1.239   IN

A data structure reference and name conflict resolution qualifier.

MOVE "abc" TO field IN the-record IN the-structure

Synonym for OF

4.1.240   INDEX

01 cursor-var USAGE INDEX.

SET cursor-var UP BY 1.

4.1.241   INDEXED

An ISAM file organization.

environment division.
input-output section.
file-control.
   select optional indexing
   assign to "indexing.dat"
   organization is indexed
   access mode is dynamic
   record key is keyfield of indexing-record
   alternate record key is splitkey of indexing-record
       with duplicates
   .

Sets an indexing control identifier for OCCURS data arrays.

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

GROUP INDICATE is an as yet unsupported REPORT SECTION RD clause that specifies that printable item is ouput only on the first occurrence of its report group for that INITIATE, control break, or page advance.

4.1.243   INHERITS

An unsupported Object COBOL clause.

4.1.244   INITIAL

A modifier for the PROGRAM-ID clause, that causes the entire DATA DIVISION to be set to an initial state each time the subprogram is executed by CALL.

ocobol >>SOURCE FORMAT IS FIXED
      *> ***************************************************************
      *> Author:    Brian Tiffin
      *> Date:      20111226
      *> Purpose:   Small sample of INITIAL procedure division clause
      *> Tectonics: cobc -x -w -g -debug initialclause.cob
      *> ***************************************************************
       identification division.
       program-id. initialclause.

      *> -*********-*********-*********-*********-*********-*********-**
       procedure division.
       call "with-initial" end-call
       call "without-initial" end-call
       call "with-initial" end-call
       call "without-initial" end-call
       call "without-initial" end-call
       goback.
       end program initialclause.


      *> -*********-*********-*********-*********-*********-*********-**
      *> -*********-*********-*********-*********-*********-*********-**
       identification division.
       program-id. with-initial is initial.

       data division.
       working-storage section.
       01 the-value pic 99 value 42.

      *> -*********-*********-*********-*********-*********-*********-**
       procedure division.
       display "Inside with-initial with   : " the-value end-display
       multiply the-value by 2 giving the-value
           on size error
               display "size overflow" end-display
       end-multiply
       goback.
       end program with-initial.


      *> -*********-*********-*********-*********-*********-*********-**
      *> -*********-*********-*********-*********-*********-*********-**
       identification division.
       program-id. without-initial.

       data division.
       working-storage section.
       01 the-value pic 99 value 42.

      *> -*********-*********-*********-*********-*********-*********-**
       procedure division.
       display "Inside without-initial with: " the-value end-display
       multiply the-value by 2 giving the-value
           on size error
               display "size overflow" end-display
       end-multiply
       goback.
       end program without-initial.

Gives:

[btiffin@home cobol]$ ./initialclause
Inside with-initial with   : 42
Inside without-initial with: 42
Inside with-initial with   : 42
Inside without-initial with: 84
size overflow
Inside without-initial with: 84
size overflow

INITIAL sets the-value to 42 upon each and every entry, without-initial multiplies through 42, 84, 168 (or would have).

4.1.245   INITIALIZE

A sample of the INITIALIZE verb posted to opencobol.org by human

OCOBOL*-----------------------------------------------------------------
       IDENTIFICATION DIVISION.
       PROGRAM-ID. 'INITTEST'.
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       SPECIAL-NAMES. DECIMAL-POINT IS COMMA.
       INPUT-OUTPUT SECTION.
       DATA DIVISION.
      *
       WORKING-STORAGE SECTION.
      *
       77  mychar      pic x.
       77  mynumeric   pic 9.
       01  REC-TEST BASED.
           03 REC-TEST-PART1 PIC X(10) value all '9'.
           03 REC-TEST-PART2 PIC X(10) value all 'A'.
       01  fillertest.
           03 fillertest-1 PIC 9(10) value 2222222222.
           03 filler       PIC X     value '|'.
           03 fillertest-2 PIC X(10) value all 'A'.
           03 filler       PIC 9(03) value 111.
           03 filler       PIC X     value '.'.
      *-----------------------------------------------------------------
       LINKAGE SECTION.
      *-----------------------------------------------------------------
       PROCEDURE DIVISION.
      *-----------------------------------------------------------------
       Main section.
       00.
      *
           display 'fillertest '
                   'on start:'
           end-display
           display fillertest
           end-display
           accept  mychar
      *
           initialize fillertest
           display 'fillertest '
                   'after initialize:'
           end-display
           display fillertest
           end-display
           accept  mychar
      *
           initialize fillertest replacing numeric by 9
           display 'fillertest '
                   'after initialize replacing numeric by 9:'
           end-display
           display fillertest
           end-display
           accept  mychar
      *
           initialize fillertest replacing alphanumeric by 'X'
           display 'fillertest '
                   'after initialize replacing alphanumeric by "X":'
           end-display
           display fillertest
           end-display
           accept  mychar
      *
           initialize fillertest replacing alphanumeric by all 'X'
           display 'fillertest '
                   'after initialize replacing alphanumeric by all "X":'
           end-display
           display fillertest
           end-display
           accept  mychar
      *
           initialize fillertest with filler
           display 'fillertest '
                   'after initialize with filler:'
           end-display
           display fillertest
           end-display
           accept  mychar
      *
           initialize fillertest all to value
           display 'fillertest '
                   'after initialize all to value:'
           end-display
           display fillertest
           end-display
           accept  mychar
      *
           ALLOCATE  REC-TEST
           display 'REC-TEST after allocating:'
           end-display
           display REC-TEST
           end-display
           accept  mychar
      *
           initialize REC-TEST all to value
           display 'REC-TEST after initalize all to value:'
           end-display
           display REC-TEST
           end-display
           accept  mychar
      *
           stop run
      *
           continue.
       ex. exit program.
      *-----------------------------------------------------------------
      *--- End of program INITTEST -------------------------------------

Outputs:

fillertest on start:
2222222222|AAAAAAAAAA111.
fillertest after initialize:
0000000000|          111.
fillertest after initialize replacing numeric by 9:
0000000009|          111.
fillertest after initialize replacing alphanumeric by "X":
0000000009|X         111.
fillertest after initialize replacing alphanumeric by all "X":
0000000009|XXXXXXXXXX111.
fillertest after initialize with filler:
0000000000           000
fillertest after initialize all to value:
2222222222|AAAAAAAAAA111.
REC-TEST after allocating:

REC-TEST after initalize all to value:
9999999999AAAAAAAAAA

4.1.246   INITIALIZED

A modifier for the ALLOCATE verb, filling the target with a default value.

77 based-var   PIC X(9) BASED VALUE "ALLOCATED".
77 pointer-var USAGE POINTER.

ALLOCATE based-var
DISPLAY ":" based-var ":" END-DISPLAY
FREE based-var
ALLOCATE based-var INITIALIZED RETURNING pointer-var
DISPLAY ":" based-var ":" END-DISPLAY

displays:

:         :
:ALLOCATED:

4.1.247   INITIATE

Initialize internal storage for named REPORT SECTION entries.

Not currently (February 2013) supported.

4.1.248   INPUT

A mode of the OPEN verb for file access.

OPEN INPUT file

A SORT clause allowing programmer controlled input read passes where sortable records are passed to the sort algorithm using RELEASE.

procedure division.
sort sort-work
    on descending key work-rec
    collating sequence is mixed
    input procedure is sort-transform
    output procedure is output-uppercase.

display sort-return end-display.
goback.

4.1.249   INPUT-OUTPUT

A section in the ENVIRONMENT DIVISION of a COBOL source file containing FILE and I-O control paragraphs.

environment division.
input-output section.
file-control.
    select htmlfile
    assign to filename
    organization is record sequential.

OpenCOBOL supports

paragraphs within the INPUT-OUTPUT SECTION.

4.1.250   INSPECT

Provides very powerful parsing and replacement to COBOL and OpenCOBOL supports the full gamet of options.

ocobol identification division.
       program-id. inspecting.

       data division.
       working-storage section.
       01  ORIGINAL            pic XXXX/XX/XXBXX/XX/XXXXXXX/XX.
       01  DATEREC             pic XXXX/XX/XXBXX/XX/XXXXXXX/XX.

       procedure division.

       move function when-compiled to DATEREC ORIGINAL

       INSPECT DATEREC REPLACING ALL "/" BY ":" AFTER INITIAL SPACE

       display
           "Intrinsic function WHEN-COMPILED " ORIGINAL
       end-display
       display
           " after INSPECT REPLACING         " DATEREC
       end-display

       goback.
       end program inspecting.

Example output:

Intrinsic function WHEN-COMPILED 2010/03/25 23/05/0900-04/00
 after INSPECT REPLACING         2010/03/25 23:05:0900-04:00

4.1.252   INTERFACE-ID

An unsupported Object COBOL clause in the IDENTIFICATION division.

4.1.253   INTO

Division.

DIVIDE A INTO B GIVING C.

4.1.254   INTRINSIC

Used in REPOSITORY to allow the optional use of “FUNCTION” keyword.

environment division.
configuration section.
repository.
    function all intrinsic.

The source unit will now allow for program lines such as

move trim("  abc") to dest
move function trim("  abc") to dest

to compile the same code.

4.1.255   INVALID

Key exception imperative phrase.

READ filename-1
    INVALID KEY
        DISPLAY "Bad key"
    NOT INVALID KEY
        DISPLAY "Good read"
END-READ

4.1.256   INVOKE

Unsupported Object COBOL method call.

4.1.257   IS

Readability word. A IS LESS THAN B is equivalent to A LESS B.

4.1.259   JUSTIFIED

Tweaks storage rules in wierd JUST ways, lessening the voodoo behind MOVE instructions, he said, sarcastically.

77 str1 pic x(40) justified right.

4.1.260   KEY

Multi use, always means key:

- RELATIVE KEY IS
- ALTERNATE RECORD KEY IS
- NOT INVALID KEY
- SORT filename ON DESCENDING KEY keyfield
- START indexing KEY IS LESS THAN keyfield

4.1.261   KEYBOARD

A special value for Standard Input

file-control.
    select cgi-in
    assign to keyboard.

4.1.262   LABEL

A record label. As with most record labels, falling into disuse.

4.1.263   LAST

Used in START to prepare a read of the last record. A recognized but unsupported Report Writer clause.

START filename-1 LAST
    INVALID KEY
        MOVE ZERO TO record-count
        >>D DISPLAY "No last record for " filename-1 END-DISPLAY
END-START

4.1.264   LC_ALL

A reserved but unsupported category group. See Setting Locale. OpenCOBOL is ‘locale’ aware, but it is currently more external than in COBOL source. For now, it is safest to assume LC_ALL=C, but this can be configured differently when OpenCOBOL is built.

4.1.265   LC_COLLATE

A reserved but unsupported category name. Will be used with SET.

4.1.266   LC_CTYPE

A reserved but unsupported Locale category name. Will be used with SET.

4.1.267   LC_MESSAGES

A reserved but unsupported category name. See Setting Locale. OpenCOBOL is ‘locale’ aware, but it is currently more external than in COBOL source.

OpenCOBOL 2.0 extends locale support to the compiler messages.

$ export LC_MESSAGES=es_ES
$ cobc -x fdfgffd.cob
cobc: fdfgffd.cob: No existe el fichero o el directorio

4.1.268   LC_MONETARY

A reserved but unsupported Locale category name. Will be used with SET.

4.1.269   LC_NUMERIC

A reserved but unsupported Locale category name. Will be used with SET.

4.1.270   LC_TIME

A reserved but unsupported Locale category name. Will be used with SET.

4.1.271   LEADING

Multipurpose.

DISPLAY FUNCTION TRIM(var-1 LEADING) END-DISPLAY

INSPECT FUNCTION REVERSE(TEST-CASE)
    TALLYING B-COUNT
    FOR LEADING ' '.
DISPLAY B-COUNT.

INSPECT X REPLACING LEADING ZEROS BY SPACES.

as well as use in the COBOL preprocessor:

COPY "copy.inc"
    REPLACING LEADING ==TEST== BY ==FIRST==
              LEADING ==NORM== BY ==SECOND==.

4.1.273   LENGTH

A ‘cell-count’ length. Not always the same as BYTE-LENGTH.

4.1.274   LESS

A comparison operation.

IF requested LESS THAN OR EQUAL TO balance
    PERFORM transfer
ELSE
    PERFORM reject
END-IF

4.1.275   LIMIT

Recognized but unsupported Report Writer clause.

4.1.276   LIMITS

Recognized but unsupported Report Writer clause.

4.1.277   LINAGE

LINAGE is a SPECIAL-REGISTER supported by OpenCOBOL. A counter is maintained for file WRITE and can be used for pageing and other control.

COBOL *****************************************************************
      * Example of LINAGE File Descriptor
      * Author: Brian Tiffin
      * Date:   10-July-2008
      * Tectonics: $ cocb -x linage.cob
      *            $ ./linage <filename ["linage.cob"]>
      *            $ cat -n mini-report
      *****************************************************************
       IDENTIFICATION DIVISION.
       PROGRAM-ID. linage-demo.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
          select optional data-file assign to file-name
              organization is line sequential
              file status is data-file-status.
          select mini-report assign to "mini-report".

       DATA DIVISION.
       FILE SECTION.
       FD  data-file.
       01  data-record.
          88 endofdata        value high-values.
          02 data-line        pic x(80).
       FD  mini-report
          linage is 16 lines
              with footing at 15
              lines at top 2
              lines at bottom 2.
       01  report-line         pic x(80).

       WORKING-STORAGE SECTION.
       01  command-arguments   pic x(1024).
       01  file-name           pic x(160).
       01  data-file-status    pic 99.
       01  lc                  pic 99.
       01  report-line-blank.
          02 filler           pic x(18) value all "*".
          02 filler           pic x(05) value spaces.
          02 filler           pic x(34)
              VALUE "THIS PAGE INTENTIONALLY LEFT BLANK".
          02 filler           pic x(05) value spaces.
          02 filler           pic x(18) value all "*".
       01  report-line-data.
          02 body-tag         pic 9(6).
          02 line-3           pic x(74).
       01  report-line-header.
          02 filler           pic x(6) VALUE "PAGE: ".
          02 page-no          pic 9999.
          02 filler           pic x(24).
          02 filler           pic x(5) VALUE " LC: ".
          02 header-tag       pic 9(6).
          02 filler           pic x(23).
          02 filler           pic x(6) VALUE "DATE: ".
          02 page-date        pic x(6).

       01  page-count          pic 9999.

       PROCEDURE DIVISION.

       accept command-arguments from command-line end-accept.
       string
          command-arguments delimited by space
          into file-name
       end-string.
       if file-name equal spaces
          move "linage.cob" to file-name
       end-if.

       open input data-file.
       read data-file
          at end
              display
                   "File: " function trim(file-name) " open error"
              end-display
              go to early-exit
       end-read.

       open output mini-report.

       write report-line
          from report-line-blank
       end-write.

       move 1 to page-count.
       accept page-date from date end-accept.
       move page-count to page-no.
       write report-line
          from report-line-header
          after advancing page
       end-write.

       perform readwrite-loop until endofdata.

       display
          "Normal termination, file name: "
          function trim(file-name)
          " ending status: "
          data-file-status
       end-display.
       close mini-report.

      * Goto considered harmful?  Bah!  :)
       early-exit.
       close data-file.
       exit program.
       stop run.

      ****************************************************************
       readwrite-loop.
       move data-record to report-line-data
       move linage-counter to body-tag
       write report-line from report-line-data
          end-of-page
              add 1 to page-count end-add
              move page-count to page-no
              move linage-counter to header-tag
              write report-line from report-line-header
                  after advancing page
              end-write
       end-write
       read data-file
          at end set endofdata to true
       end-read
       .

      *****************************************************************
      * Commentary
      * LINAGE is set at a 20 line logical page
      *  16 body lines
      *   2 top lines
      *   A footer line at 15 (inside the body count)
      *   2 bottom lines
      * Build with:
      * $ cobc -x -Wall -Wtruncate linage.cob
      * Evaluate with:
      * $ ./linage
      * This will read in linage.cob and produce a useless mini-report
      * $ cat -n mini-report
      *****************************************************************
       END PROGRAM linage-demo.

Using

$ ./linage except.cob

Produces a mini-report of:

******************     THIS PAGE INTENTIONALLY LEFT BLANK     ******************


















PAGE: 0001                         LC: 000000                       DATE: 090206
000001 IDENTIFICATION DIVISION.
000002 PROGRAM-ID. MINIPROG.
000003 ENVIRONMENT DIVISION.
000004 CONFIGURATION SECTION.
000005 SOURCE-COMPUTER. LINUX.
000006 OBJECT-COMPUTER. LINUX.
000007 SPECIAL-NAMES.
000008 INPUT-OUTPUT SECTION.
000009 FILE-CONTROL.
000010 SELECT PRINTFILE ASSIGN TO "XXRXWXX"
000011 FILE STATUS RXWSTAT.
000012 DATA DIVISION.
000013 FILE SECTION.
000014 FD PRINTFILE.





PAGE: 0002                         LC: 000015                       DATE: 090206
000001 01 PRINTREC PIC X(132).
000002 WORKING-STORAGE SECTION.
000003 01 RXWSTAT PIC XX.
000004 01 str     pic x(4).
000005 PROCEDURE DIVISION.
000006 A00-MAIN SECTION.
000007 001-MAIN-PROCEDURE.
000008 OPEN INPUT PRINTFILE.
000009 DISPLAY "File Status: " RXWSTAT.
000010 DISPLAY "EXCEPTION-FILE: " FUNCTION EXCEPTION-FILE.
000011 DISPLAY "Return Length: "
000012 FUNCTION LENGTH (FUNCTION EXCEPTION-FILE).
000013 DISPLAY "EXCEPTION-STATUS: " FUNCTION EXCEPTION-STATUS.
000014 DISPLAY "EXCEPTION-STATEMENT: " FUNCTION EXCEPTION-STATEMENT.





PAGE: 0003                         LC: 000015                       DATE: 090206
000001 STRING "TOOLONG" DELIMITED SIZE INTO RXWSTAT.
000002 DISPLAY "EXCEPTION-STATUS: " FUNCTION EXCEPTION-STATUS.
000003 DISPLAY "EXCEPTION-STATEMENT: " FUNCTION EXCEPTION-STATEMENT.
000004 DISPLAY "EXCEPTION-LOCATION: " FUNCTION EXCEPTION-LOCATION.
000005 STOP RUN.

See except.cob under the FUNCTION EXCEPTION-STATUS entry.

4.1.278   LINAGE-COUNTER

An internal OpenCOBOL noun, or Special Register. Value is readonly and is maintained during WRITEs to files that have a LINAGE clause. Useful for quick reports and logical page layouts.

4.1.279   LINE

LINE SEQUENTIAL files. Screen section line control.

4.1.280   LINE-COUNTER

Special register for the unsupported Report Writer.

4.1.281   LINES

Screen section line control, screen occurs control and area scrolling.

4.1.282   LINKAGE

A SECTION in the DATA DIVISION. Used for call frame data handling when the current run unit may not be in charge of the location of working storage. Defaults to uninitialized references which must be set with USING in a CALL or explicitly with SET ADDRESS. References without initialization will cause an addressing segfault.

4.1.283   LOCAL-STORAGE

A SECTION in the DATA DIVISION. Data defined in local storage will be local to the running module and re-entrant within subprogram call trees.

4.1.284   LOCALE

Unsupported in OpenCOBOL 1.1pre-rel. Support added in 2.0

A SPECIAL-NAMES entry giving OpenCOBOL an international flair.

ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES.
    LOCALE spanish IS 'ES_es'.

4.1.285   LOCK

Record management.

SELECT filename-1 ASSIGN TO 'master.dat' LOCK MODE IS MANUAL.

4.1.286   LOW-VALUE

A figurative ALPHABETIC constant, being the lowest character value in the COLLATING sequence.

MOVE LOW-VALUE TO alphanumeric-1.

IF alphabetic-1 EQUALS LOW-VALUE
    DISPLAY "Failed validation" END-DISPLAY
END-IF.

It’s invalid to MOVE LOW-VALUE to a numeric field.

4.1.287   LOW-VALUES

A pluralized form of LOW-VALUE. Equivalent.

MOVE LOW-VALUES TO alphanumeric-1.

4.1.288   LOWLIGHT

A screen attribute for DISPLAY and SCREEN SECTION fields.

SCREEN SECTION.
01 example.
    05 FILLER
        LINE 1 COLUMN 10
        VALUE IS "Example:"
        LOWLIGHT.

Will display the Example: legend in a dimmed video if supported with the current terminal settings.

4.1.289   MANUAL

LOCK MODE IS MANUAL WITH LOCK ON MULTIPLE RECORDS. See AUTOMATIC and EXCLUSIVE for more LOCK options.

4.1.290   MEMORY

An OBJECT-COMPUTER clause.

ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
OBJECT-COMPUTER.
MEMORY SIZE IS 8 CHARACTERS.

4.1.291   MERGE

Combines two or more identically sequenced files on a set of specified keys.

MERGE sort-file
    ON DESCENDING KEY key-field-1
    WITH DUPLICATES IN ORDER
    COLLATING SEQUENCE IS user-alphabet
    USING filename-1 filename-2
    GIVING filename-3

4.1.292   MESSAGE

Unsupported Communication Section clause.

4.1.293   METHOD

Unsupported Object COBOL feature.

4.1.294   METHOD-ID

Unsupported Object COBOL feature.

4.1.295   MINUS

Screen section relative line and column control.

05 some-field pic x(16)
    line number is plus 1
    column number is minus 8

4.1.297   MOVE

A workhorse of the COBOL paradigm. MOVE is highly flexible, intelligent, safe and sometimes perplexing data movement verb.

01 alphanum-3              PIC XXX.
01 num2                    PIC 99.

MOVE "ABCDEFG" TO xvar3
DISPLAY xvar3 END-DISPLAY

MOVE 12345 TO num2
DISPLAY num2 END-DISPLAY

displays:

ABC
45

Note the 45, MOVE uses a right to left rule when moving numerics.

Groups can be moved with

MOVE CORRESPONDING ident-1 TO ident-2

in which case only the group items of the same name will be transferred from the ident-1 group to the ident-2 fields.

4.1.298   MULTIPLE

LOCK MODE IS MANUAL WITH LOCK ON MULTIPLE RECORDS.

4.1.299   MULTIPLY

A mathematic operation.

MULTIPLY var-1 BY var-2 GIVING var-3
    ON SIZE ERROR
        SET invalid-result TO TRUE
END-MULTIPLY

4.1.300   NATIONAL

NATIONAL character usage. Not yet supported. OpenCOBOL does support PICTURE N.

4.1.303   NEGATIVE

Conditional expression.

IF a IS NEGATIVE
    SET in-the-red TO TRUE
END-IF

4.1.304   NESTED

An unsupported program-protoype CALL clause.

4.1.306   NO

Specify NO locks, NO sharing, NO rewind.

CLOSE filename-1 WITH NO REWIND

READ file-1 WITH NO LOCK

4.1.307   NONE

Unsupported DEFAULT IS NONE.

4.1.308   NORMAL

Program return control

STOP RUN WITH NORMAL STATUS status-val

See ERROR

4.1.309   NOT

Conditional negation. See AND, OR. Also used in operational declaratives such as NOT ON SIZE ERROR, in which case the operation succeeded without overflowing the receiving data field.

IF NOT testing
    CALL "thing"
        NOT ON EXCEPTION
            DISPLAY "Linkage to thing, OK" END-DISPLAY
    END-CALL
END-IF

4.1.310   NULL

Void. A zero address pointer. A symbolic literal.

CALL "thing" RETURNING NULL END-CALL

SET ADDRESS OF ptr TO NULL

IF ptr EQUAL NULL
    DISPLAY "ptr not valid" END-DISPLAY
END-IF

MOVE CONCATENATE(TRIM(cbl-string TRAILING) NULL) TO c-string

4.1.311   NULLS

Plural of NULL.

MOVE ALL NULLS TO var

4.1.312   NUMBER

Screen section LINE COLUMN control.

05 some-field pic x(16) LINE NUMBER 5.

4.1.316   OBJECT

Unsupported Object COBOL feature.

4.1.317   OBJECT-COMPUTER

Environment division, configuration section run-time machine paragraph.

OpenCOBOL supports

OCOBOL identification division.
       program-id. runtime-computer.

       environment division.
       configuration section.
       object-computer.
           memory size is 8 characters
           program collating sequence is bigiron-alphabet
           segment-limit is 64
           character classificiation is spanish-locale.
       repository.
           function all intrinsic.
       special-names.
           alphabet bigiron-alphabet is ebcdic
           symbolic characters BS  is  9
                               TAB is 10
                               LF  is 11
                           NEWLINE is 11
                               CMA is 45
           locale spanish-locale is "es_ES".

4.1.318   OBJECT-REFERENCE

Unsupported Object COBOL feature.

4.1.319   OCCURS

Controls multiple occurances of data structures.

01 main-table.
   03 main-record occurs 366 times depending on the-day.
      05 main-field pic x occurs 132 times depending on the-len.

4.1.320   OF

A data structure reference and name conflict resolution qualifier.

MOVE "abc" TO the-field OF the-record OF the-structure

Synonym for IN

4.1.321   OFF

Turn off a switch. See ON.

SPECIAL-NAMES.
    SWITCH-1 IS mainframe
        ON STATUS IS bigiron
        OFF STATUS IS pc

...

SET mainframe TO OFF

4.1.322   OMITTED

Allows for placeholders in call frames and testing for said placeholders. Also allows for omitted label records, and void returns. OMITTED is only allowed with BY REFERENCE data.

CALL "thing" USING
    BY REFERENCE string-var
    BY VALUE number-var
    BY REFERENCE OMITTED
    GIVING NULL
END-CALL

...

PROGRAM-ID. thing.
DATA DIVISION.
WORKING-STORAGE SECTION.
77 default-float usage float-long.

LINKAGE-SECTION.
77 string-var pic x(80).
77 number-var pic 9(8).
77 float-var usage float-long.

PROCEDURE DIVISION
    USING
        BY REFERENCE OPTIONAL string-var
        BY VALUE number-var
        BY REFERENCE OPTIONAL float-var
    RETURNING OMITTED.

IF float-var IS OMITTED
    SET ADDRESS OF float-var TO default-float
END-IF

4.1.323   ON

Turn on a switch. See OFF.

SPECIAL-NAMES.
    SWITCH-1 IS mainframe
        ON STATUS IS bigiron
        OFF STATUS IS pc

...

SET mainframe TO ON

Starts declaratives.

ADD 1 TO wafer-thin-mint
    ON SIZE ERROR
        SET get-a-bucket TO TRUE
END-ADD

See SIZE, EXCEPTION.

4.1.324   ONLY

Sharing control. SHARING WITH READ ONLY

4.1.325   OPEN

Opens a file selector. Modes include INPUT, OUTPUT, I-O, EXTEND. May be OPTIONAL in the FD.

OPEN INPUT SHARING WITH ALL OTHER infile
OPEN EXTEND SHARING WITH NO OTHER myfile

4.1.326   OPTIONAL

Allows for referencing non-existent files. Allows for optionally OMITTED call arguments.

Code below shows optional file open and optional CALL arguments.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
    SELECT OPTIONAL nofile ASSIGN TO "file.not"
           ORGANIZATION IS LINE SEQUENTIAL.

...

DATA DIVISION.
LINKAGE SECTION.
77 arg PIC 99.

PROCEDURE DIVISION USING OPTIONAL arg

OPEN INPUT nofile
CLOSE nofile

IF arg IS OMITTED OR NOT NUMERIC
    MOVE 0 TO RETURN-CODE
ELSE
    MOVE arg TO RETURN-CODE
END-IF
GOBACK.

4.1.327   OPTIONS

A currently unsupported paragraph of the IDENTIFICATION division.

4.1.328   OR

Logical operation. See AND, NOT. OpenCOBOL supports COBOL’s logical expression shortcuts. Order of precedence can be controlled with parenthesis, and default to NOT, AND, OR, right to left.

IF A NOT EQUAL 1 OR 2 OR 3 OR 5
    DISPLAY "FORE!" END-DISPLAY
END-IF

4.1.329   ORDER

Sort clause to influence how duplicates are managed.

sort sort-work
    ascending key work-rec with duplicates in order
    using  sort-in
    giving sort-out.

In 1.1pre-rel, WITH DUPLICATES IN ORDER is a default.

4.1.330   ORGANIZATION

Defines a file’s storage organization. One of INDEXED, RELATIVE, SEQUENTIAL. OpenCOBOL also supports a LINE SEQUENTIAL structure.

4.1.331   OTHER

File sharing option, ALL OTHER, NO OTHER.

EVALUATE‘s else clause.

OCOBOL*> Here be dragons <*
       EVALUATE TRUE
           WHEN a IS 1
               PERFORM paragraph-1
           WHEN OTHER
               ALTER paragraph-1 TO paragraph-2
               PERFORM paragraph-3
       END-EVALUATE

4.1.332   OUTPUT

File OPEN mode. Procedure named in SORT

sort sort-work
    on descending key work-rec
    collating sequence is mixed
    input procedure is sort-transform
    output procedure is output-uppercase.

4.1.333   OVERFLOW

Declarative clause for STRING and UNSTRING that will trigger on space overflow conditions.

4.1.334   OVERLINE

A display control for SCREEN section fields.

4.1.335   OVERRIDE

Unsupportd Object COBOL METHOD-ID clause.

4.1.336   PACKED-DECIMAL

Numeric USAGE clause, equivalent to COMPUTATIONAL-3. Holds each digit in a 4-bit field.

From the opencobol-2.0 tarball testsuite

OCOBOL
       IDENTIFICATION   DIVISION.
       PROGRAM-ID.      prog.
       DATA             DIVISION.
       WORKING-STORAGE  SECTION.
       01 G-1.
         02 X-1         PIC 9(1) VALUE 1
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-2.
         02 X-2         PIC 9(2) VALUE 12
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-3.
         02 X-3         PIC 9(3) VALUE 123
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-4.
         02 X-4         PIC 9(4) VALUE 1234
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-5.
         02 X-5         PIC 9(5) VALUE 12345
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-6.
         02 X-6         PIC 9(6) VALUE 123456
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-7.
         02 X-7         PIC 9(7) VALUE 1234567
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-8.
         02 X-8         PIC 9(8) VALUE 12345678
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-9.
         02 X-9         PIC 9(9) VALUE 123456789
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-10.
         02 X-10        PIC 9(10) VALUE 1234567890
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-11.
         02 X-11        PIC 9(11) VALUE 12345678901
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-12.
         02 X-12        PIC 9(12) VALUE 123456789012
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-13.
         02 X-13        PIC 9(13) VALUE 1234567890123
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-14.
         02 X-14        PIC 9(14) VALUE 12345678901234
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-15.
         02 X-15        PIC 9(15) VALUE 123456789012345
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-16.
         02 X-16        PIC 9(16) VALUE 1234567890123456
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-17.
         02 X-17        PIC 9(17) VALUE 12345678901234567
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-18.
         02 X-18        PIC 9(18) VALUE 123456789012345678
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-S1.
         02 X-S1        PIC S9(1) VALUE -1
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-S2.
         02 X-S2        PIC S9(2) VALUE -12
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-S3.
         02 X-S3        PIC S9(3) VALUE -123
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-S4.
         02 X-S4        PIC S9(4) VALUE -1234
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-S5.
         02 X-S5        PIC S9(5) VALUE -12345
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-S6.
         02 X-S6        PIC S9(6) VALUE -123456
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-S7.
         02 X-S7        PIC S9(7) VALUE -1234567
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-S8.
         02 X-S8        PIC S9(8) VALUE -12345678
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-S9.
         02 X-S9        PIC S9(9) VALUE -123456789
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-S10.
         02 X-S10       PIC S9(10) VALUE -1234567890
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-S11.
         02 X-S11       PIC S9(11) VALUE -12345678901
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-S12.
         02 X-S12       PIC S9(12) VALUE -123456789012
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-S13.
         02 X-S13       PIC S9(13) VALUE -1234567890123
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-S14.
         02 X-S14       PIC S9(14) VALUE -12345678901234
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-S15.
         02 X-S15       PIC S9(15) VALUE -123456789012345
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-S16.
         02 X-S16       PIC S9(16) VALUE -1234567890123456
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-S17.
         02 X-S17       PIC S9(17) VALUE -12345678901234567
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       01 G-S18.
         02 X-S18       PIC S9(18) VALUE -123456789012345678
                        PACKED-DECIMAL.
         02 FILLER      PIC X(18) VALUE SPACE.
       PROCEDURE        DIVISION.
      *>   Dump all values <*
           CALL "dump" USING G-1
           END-CALL.
           CALL "dump" USING G-2
           END-CALL.
           CALL "dump" USING G-3
           END-CALL.
           CALL "dump" USING G-4
           END-CALL.
           CALL "dump" USING G-5
           END-CALL.
           CALL "dump" USING G-6
           END-CALL.
           CALL "dump" USING G-7
           END-CALL.
           CALL "dump" USING G-8
           END-CALL.
           CALL "dump" USING G-9
           END-CALL.
           CALL "dump" USING G-10
           END-CALL.
           CALL "dump" USING G-11
           END-CALL.
           CALL "dump" USING G-12
           END-CALL.
           CALL "dump" USING G-13
           END-CALL.
           CALL "dump" USING G-14
           END-CALL.
           CALL "dump" USING G-15
           END-CALL.
           CALL "dump" USING G-16
           END-CALL.
           CALL "dump" USING G-17
           END-CALL.
           CALL "dump" USING G-18
           END-CALL.
           CALL "dump" USING G-S1
           END-CALL.
           CALL "dump" USING G-S2
           END-CALL.
           CALL "dump" USING G-S3
           END-CALL.
           CALL "dump" USING G-S4
           END-CALL.
           CALL "dump" USING G-S5
           END-CALL.
           CALL "dump" USING G-S6
           END-CALL.
           CALL "dump" USING G-S7
           END-CALL.
           CALL "dump" USING G-S8
           END-CALL.
           CALL "dump" USING G-S9
           END-CALL.
           CALL "dump" USING G-S10
           END-CALL.
           CALL "dump" USING G-S11
           END-CALL.
           CALL "dump" USING G-S12
           END-CALL.
           CALL "dump" USING G-S13
           END-CALL.
           CALL "dump" USING G-S14
           END-CALL.
           CALL "dump" USING G-S15
           END-CALL.
           CALL "dump" USING G-S16
           END-CALL.
           CALL "dump" USING G-S17
           END-CALL.
           CALL "dump" USING G-S18
           END-CALL.
           INITIALIZE X-1.
           CALL "dump" USING G-1
           END-CALL.
           INITIALIZE X-2.
           CALL "dump" USING G-2
           END-CALL.
           INITIALIZE X-3.
           CALL "dump" USING G-3
           END-CALL.
           INITIALIZE X-4.
           CALL "dump" USING G-4
           END-CALL.
           INITIALIZE X-5.
           CALL "dump" USING G-5
           END-CALL.
           INITIALIZE X-6.
           CALL "dump" USING G-6
           END-CALL.
           INITIALIZE X-7.
           CALL "dump" USING G-7
           END-CALL.
           INITIALIZE X-8.
           CALL "dump" USING G-8
           END-CALL.
           INITIALIZE X-9.
           CALL "dump" USING G-9
           END-CALL.
           INITIALIZE X-10.
           CALL "dump" USING G-10
           END-CALL.
           INITIALIZE X-11.
           CALL "dump" USING G-11
           END-CALL.
           INITIALIZE X-12.
           CALL "dump" USING G-12
           END-CALL.
           INITIALIZE X-13.
           CALL "dump" USING G-13
           END-CALL.
           INITIALIZE X-14.
           CALL "dump" USING G-14
           END-CALL.
           INITIALIZE X-15.
           CALL "dump" USING G-15
           END-CALL.
           INITIALIZE X-16.
           CALL "dump" USING G-16
           END-CALL.
           INITIALIZE X-17.
           CALL "dump" USING G-17
           END-CALL.
           INITIALIZE X-18.
           CALL "dump" USING G-18
           END-CALL.
           INITIALIZE X-S1.
           CALL "dump" USING G-S1
           END-CALL.
           INITIALIZE X-S2.
           CALL "dump" USING G-S2
           END-CALL.
           INITIALIZE X-S3.
           CALL "dump" USING G-S3
           END-CALL.
           INITIALIZE X-S4.
           CALL "dump" USING G-S4
           END-CALL.
           INITIALIZE X-S5.
           CALL "dump" USING G-S5
           END-CALL.
           INITIALIZE X-S6.
           CALL "dump" USING G-S6
           END-CALL.
           INITIALIZE X-S7.
           CALL "dump" USING G-S7
           END-CALL.
           INITIALIZE X-S8.
           CALL "dump" USING G-S8
           END-CALL.
           INITIALIZE X-S9.
           CALL "dump" USING G-S9
           END-CALL.
           INITIALIZE X-S10.
           CALL "dump" USING G-S10
           END-CALL.
           INITIALIZE X-S11.
           CALL "dump" USING G-S11
           END-CALL.
           INITIALIZE X-S12.
           CALL "dump" USING G-S12
           END-CALL.
           INITIALIZE X-S13.
           CALL "dump" USING G-S13
           END-CALL.
           INITIALIZE X-S14.
           CALL "dump" USING G-S14
           END-CALL.
           INITIALIZE X-S15.
           CALL "dump" USING G-S15
           END-CALL.
           INITIALIZE X-S16.
           CALL "dump" USING G-S16
           END-CALL.
           INITIALIZE X-S17.
           CALL "dump" USING G-S17
           END-CALL.
           INITIALIZE X-S18.
           CALL "dump" USING G-S18
           END-CALL.
           MOVE ZERO TO X-1.
           CALL "dump" USING G-1
           END-CALL.
           MOVE ZERO TO X-2.
           CALL "dump" USING G-2
           END-CALL.
           MOVE ZERO TO X-3.
           CALL "dump" USING G-3
           END-CALL.
           MOVE ZERO TO X-4.
           CALL "dump" USING G-4
           END-CALL.
           MOVE ZERO TO X-5.
           CALL "dump" USING G-5
           END-CALL.
           MOVE ZERO TO X-6.
           CALL "dump" USING G-6
           END-CALL.
           MOVE ZERO TO X-7.
           CALL "dump" USING G-7
           END-CALL.
           MOVE ZERO TO X-8.
           CALL "dump" USING G-8
           END-CALL.
           MOVE ZERO TO X-9.
           CALL "dump" USING G-9
           END-CALL.
           MOVE ZERO TO X-10.
           CALL "dump" USING G-10
           END-CALL.
           MOVE ZERO TO X-11.
           CALL "dump" USING G-11
           END-CALL.
           MOVE ZERO TO X-12.
           CALL "dump" USING G-12
           END-CALL.
           MOVE ZERO TO X-13.
           CALL "dump" USING G-13
           END-CALL.
           MOVE ZERO TO X-14.
           CALL "dump" USING G-14
           END-CALL.
           MOVE ZERO TO X-15.
           CALL "dump" USING G-15
           END-CALL.
           MOVE ZERO TO X-16.
           CALL "dump" USING G-16
           END-CALL.
           MOVE ZERO TO X-17.
           CALL "dump" USING G-17
           END-CALL.
           MOVE ZERO TO X-18.
           CALL "dump" USING G-18
           END-CALL.
           MOVE ZERO TO X-S1.
           CALL "dump" USING G-S1
           END-CALL.
           MOVE ZERO TO X-S2.
           CALL "dump" USING G-S2
           END-CALL.
           MOVE ZERO TO X-S3.
           CALL "dump" USING G-S3
           END-CALL.
           MOVE ZERO TO X-S4.
           CALL "dump" USING G-S4
           END-CALL.
           MOVE ZERO TO X-S5.
           CALL "dump" USING G-S5
           END-CALL.
           MOVE ZERO TO X-S6.
           CALL "dump" USING G-S6
           END-CALL.
           MOVE ZERO TO X-S7.
           CALL "dump" USING G-S7
           END-CALL.
           MOVE ZERO TO X-S8.
           CALL "dump" USING G-S8
           END-CALL.
           MOVE ZERO TO X-S9.
           CALL "dump" USING G-S9
           END-CALL.
           MOVE ZERO TO X-S10.
           CALL "dump" USING G-S10
           END-CALL.
           MOVE ZERO TO X-S11.
           CALL "dump" USING G-S11
           END-CALL.
           MOVE ZERO TO X-S12.
           CALL "dump" USING G-S12
           END-CALL.
           MOVE ZERO TO X-S13.
           CALL "dump" USING G-S13
           END-CALL.
           MOVE ZERO TO X-S14.
           CALL "dump" USING G-S14
           END-CALL.
           MOVE ZERO TO X-S15.
           CALL "dump" USING G-S15
           END-CALL.
           MOVE ZERO TO X-S16.
           CALL "dump" USING G-S16
           END-CALL.
           MOVE ZERO TO X-S17.
           CALL "dump" USING G-S17
           END-CALL.
           MOVE ZERO TO X-S18.
           CALL "dump" USING G-S18
           END-CALL.
           STOP RUN.

With a support file to dump the first 10 bytes of each record

#include <stdio.h>
#ifdef  __INTEL_COMPILER
#pragma warning ( disable : 1419 )
#endif
int dump (unsigned char *data);
int dump (unsigned char *data)
{
  int i;
  for (i = 0; i < 10; i++)
    printf ("%02x", data[i]);
  puts ("");
  return 0;
}
/**/

Which captures:

1f202020202020202020
012f2020202020202020
123f2020202020202020
01234f20202020202020
12345f20202020202020
0123456f202020202020
1234567f202020202020
012345678f2020202020
123456789f2020202020
01234567890f20202020
12345678901f20202020
0123456789012f202020
1234567890123f202020
012345678901234f2020
123456789012345f2020
01234567890123456f20
12345678901234567f20
0123456789012345678f
1d202020202020202020
012d2020202020202020
123d2020202020202020
01234d20202020202020
12345d20202020202020
0123456d202020202020
1234567d202020202020
012345678d2020202020
123456789d2020202020
01234567890d20202020
12345678901d20202020
0123456789012d202020
1234567890123d202020
012345678901234d2020
123456789012345d2020
01234567890123456d20
12345678901234567d20
0123456789012345678d
0f202020202020202020
000f2020202020202020
000f2020202020202020
00000f20202020202020
00000f20202020202020
0000000f202020202020
0000000f202020202020
000000000f2020202020
000000000f2020202020
00000000000f20202020
00000000000f20202020
0000000000000f202020
0000000000000f202020
000000000000000f2020
000000000000000f2020
00000000000000000f20
00000000000000000f20
0000000000000000000f
0c202020202020202020
000c2020202020202020
000c2020202020202020
00000c20202020202020
00000c20202020202020
0000000c202020202020
0000000c202020202020
000000000c2020202020
000000000c2020202020
00000000000c20202020
00000000000c20202020
0000000000000c202020
0000000000000c202020
000000000000000c2020
000000000000000c2020
00000000000000000c20
00000000000000000c20
0000000000000000000c
0f202020202020202020
000f2020202020202020
000f2020202020202020
00000f20202020202020
00000f20202020202020
0000000f202020202020
0000000f202020202020
000000000f2020202020
000000000f2020202020
00000000000f20202020
00000000000f20202020
0000000000000f202020
0000000000000f202020
000000000000000f2020
000000000000000f2020
00000000000000000f20
00000000000000000f20
0000000000000000000f
0c202020202020202020
000c2020202020202020
000c2020202020202020
00000c20202020202020
00000c20202020202020
0000000c202020202020
0000000c202020202020
000000000c2020202020
000000000c2020202020
00000000000c20202020
00000000000c20202020
0000000000000c202020
0000000000000c202020
000000000000000c2020
000000000000000c2020
00000000000000000c20
00000000000000000c20
0000000000000000000c

4.1.337   PADDING

Defines a character to use for short record padding.

ORGANIZATION IS LINE SEQUENTIAL PADDING CHARACTER IS '*'

4.1.338   PAGE

Write and Report writer clause.

WRITE theline AFTER ADVANCING PAGE

PAGE LIMITS ARE 66 LINES 132 COLUMNS
    HEADING iS 4 FIRST DETAIL IS 6
    LAST CONTROL HEADING IS 58
    LAST DETAIL IS 60
    FOOTING IS 62

4.1.339   PAGE-COUNTER

A special register, qualified by Report Name. Report Writer is recognized but not yet supported.

4.1.340   PARAGRAPH

An allowable EXIT point.

NAMED-PARAGRAPH.
    PERFORM FOREVER
        IF solution
            EXIT PARAGRAPH
        END-IF
        PERFORM solve-the-puzzle.
    END-PERFORM.

4.1.341   PERFORM

A COBOL procedural and inline control flow verb.

beginning.
    PERFORM FOREVER
        PERFORM miracles
    END-PERFORM
    GOBACK.

miracles.
    DISPLAY wonders END-DISPLAY.

4.1.342   PF

Report Writer alias for PAGE FOOTING.

4.1.343   PH

Report Writer alias for PAGE HEADING.

4.1.344   PIC

A commonly used shortform of PICTURE.

4.1.345   PICTURE

The PICTURE clause is easily one of COBOL’s greatest strengths. Fully detailed pictorial data definitions. The internal complexity is left to compiler authors, while developers and management are free to describe data at a very high conceptual level.

The two most common picture characters are 9 and X, for numeric and alphanumeric data respectively. For alphbetic data, A can be used.

Aside from data storage pictures, a vast array of edit pictures are allowed for control of input and output formatting.

+, -, A, B, N, X, Z, “*”, ‘CR’, ‘DB’, E, S, V, ., P, currency symbol

OpenCOBOL offers full standards support of all alpha, alphanumeric and numeric storage specifiers as well as full support for edit and numeric-edit clauses.

An example of some of the PICTURE options

*>>source format is free
*> ********************************************************************
*> Author:    jrls (John Ellis)
*> Date:      Oct-2008
*> Purpose:   formated output examples using pic strings.
*> ********************************************************************

identification division.
program-id. picstring.
data division.
working-storage section.
*><*

01  header.
    05  filler          pic xxx  value "ln".
    05  filler          pic x(11) value "    disp1".
    05  filler          pic x(11) value "    disp2".
    05  filler          pic x(11) value "    disp3".
    05  filler          pic x(11) value "    disp4".
    05  filler          pic x(12) value "    disp5".
    05  filler          pic x(9)  value "   an1".
    05  filler          pic x(14) value "      phone".
    05  filler          pic x(10) value "   date".
*><*
01  headerLines         pic x(90) value all "-".
*><*
01  displayformats.
    05  linenum         pic 99  value 1.
    05  disp1           pic zzz,zz9.99 value zero.
    05  filler          pic x value spaces.
    05  disp2           pic $zz,zz9.99 value zero.
    05  filler          pic x value spaces.
    05  disp3           pic ---,--9.99 value zero.
    05  filler          pic x value spaces.
    05  disp4           pic $-z,zz9.99 value zero.
    05  filler          pic x value spaces.
    05  disp5           pic -zz,zz9.zz- blank  zero value zero.
    05  filler          pic x value spaces.
*><*an1 is actually a string field because of the embedded blanks, thus you put value spaces.
    05  an1             pic 99b99b99    value spaces.
    05  filler          pic x value spaces.
    05  phone           pic bxxxbxxxbxxxx value spaces.
    05  filler          pic x value spaces.
    05  dispdate        pic 99/99/9999  value zero.
*><*

procedure division.
0000-start.
*><*
    display headerLines.
    display header.
    display headerLines.
*><****************************************************
    move 220.22         to disp1,
                           disp2.
    move -220.22        to disp3,
                           disp4,
                           disp5.

    inspect disp5 replacing first "-" by "(",
                            first "-" by ")".

    move 10122008       to dispdate.
*><****************************************************
*><*Please note the results of moving 'abcd' to an1.
*><*an1 will show up as 00 00 00 because alpha data was
*><*moved into instead of numeric data.
*><*
*><*The phone field will display " abc def ghij" because
*><*'b' in the pic string.
*><****************************************************
    move "abcd"         to an1.
    move "abcdefghij"   to phone.

    display displayformats.

    add 1               to linenum.
    move zero           to disp4,
                           disp5.
*><****************************************************
*><*Here after moving data to an1 and phone, I use the
*><*inspect statement to replace the blanks.
*><****************************************************
    move "123456"       to an1.
    move "5555551234"   to phone.

    inspect an1 replacing all " " by "-".

    inspect phone replacing first " " by "(",
                            first " " by ")",
                            first " " by "-".

    display displayformats.

    inspect phone converting "23456789" to "adgjmptw".
    display phone.

    perform 0010-endProgram.
*><*
0010-endProgram.
    stop run.
*><*

Outputs:

------------------------------------------------------------------------------------------
ln     disp1      disp2      disp3      disp4      disp5      an1         phone      date
------------------------------------------------------------------------------------------
01    220.22    $220.22    -220.22   $-220.22    (220.22) 00 00 00  abc def ghij 10/12/2008
02    220.22    $220.22    -220.22     $ 0.00             12-34-56 (555)555-1234 10/12/2008
(jjj)jjj-1adg

4.1.346   PLUS

Screen section relative line / column control during layout.

01 form-1 AUTO.
   05 LINE 01 COLUMN 01 VALUE "Form!".
   05 LINE PLUS 3 COLUMN 01 VALUE value-4.

4.1.347   POINTER

Allocates a restricted use variable for holding addresses.

01  c-handle        USAGE IS POINTER.

CALL "open-lib" RETURNING c-handle
    ON EXCEPTION
        DISPLAY "Can't link open-lib" END-DISPLAY
        STOP RUN RETURNING 1
END-CALL
IF c-handle EQUAL NULL
    DISPLAY "Can't open-lib" END-DISPLAY
    STOP RUN RETURNING 1
END-IF

CALL "use-lib" USING BY VALUE c-handle BY CONTENT "Hello" & x"00"
CALL "close-lib" USING BY VALUE c-handle

*> Interfacing with the C ABI is just a teenie-weenie bit of voodoo
*> Pass the REFERENCE or use RETURNING if C sets the value. Use
*>   VALUE when you want C to have its pointer, not the
*>   REFERENCE address of the COBOL POINTER.  So most inits are
*>   BY REFERENCE (or RETURNING) and most usage, including
*>   rundown of C ABI tools, is USING BY VALUE.
*> <*

4.1.348   POSITION

Alias for COLUMN in screen section layouts. Also an obsolete, recognized but not supported:

MULTIPLE FILE TAPE CONTAINS file-1 POSITION 1 file-2 POSITION 80

4.1.349   POSITIVE

Class condition.

IF amount IS POSITIVE
    DISPLAY "Not broke yet" END-DISPLAY
END-IF

4.1.350   PRESENT

Report Writer clause used for optional field and group output.

05 field PIC X(16) PRESENT WHEN sum > 0.

4.1.352   PRINTER

Special name.

SPECIAL-NAMES.
    PRINTER IS myprint

DISPLAY "test" UPON PRINTER END-DISPLAY

4.1.353   PRINTING

Report Writer declarative to SUPPRESS report printing.

4.1.354   PROCEDURE

The COBOL DIVISION that holds the executable statements. Also used with INPUT and OUTPUT sort procedures.

4.1.355   PROCEDURE-POINTER

Alias for PROGRAM-POINTER, capable of holding a callable address.

4.1.356   PROCEDURES

Debug module declarative clause.

USE FOR DEBUGGING ON ALL PROCEDURES

4.1.357   PROCEED

Used in ALTER.

ALTER paragraph-1 TO PROCEED TO paragraph-x

4.1.358   PROGRAM

An EXIT point.

EXIT PROGRAM.

4.1.359   PROGRAM-ID

The program identifier. Case sensitive, unlike all other OpenCOBOL identifiers. OpenCOBOL produces C Application Binary Interface linkable entities and this identifier must conform to those rules. Dashes in names are replaced by a hex string equivalent.

4.1.360   PROGRAM-POINTER

A data USAGE clause defining a field that can hold the executable address of a CALL routine.

77 callback USAGE PROGRAM-POINTER.
...
SET callback TO ENTRY a-program-id
CALL callback

4.1.361   PROMPT

Screen section input control.

PROMPT IS ':'

4.1.362   PROPERTY

Unsupported Object COBOL phrase.

4.1.363   PROTOTYPE

Unsupported Object COBOL phrase.

4.1.364   PURGE

Unsupported Communication Section clause.

4.1.365   QUEUE

Unsupported Communication Section clause.

4.1.366   QUOTE

A figurative constant representing ‘”’.

DISPLAY QUOTE 123 QUOTE END-DISPLAY

Outputs:

"123"

4.1.367   QUOTES

A figurative constant representing ‘”’.

01 var PICTURE X(4).

MOVE ALL QUOTES TO var
DISPLAY var END-DISPLAY

Outputs:

""""

4.1.368   RAISE

Exception handling. There IS support for exceptions in OpenCOBOL but it is currently fairly limited. See FUNCTION EXCEPTION-LOCATION for a sample. RAISE is not yet recognized.

4.1.369   RAISING

Exception handling. There IS support for exceptions in OpenCOBOL but it is currently limited. RAISING is not yet recognized.

4.1.370   RANDOM

A file access mode. RANDOM access allows seeks to any point in a file, usually by KEY.

4.1.371   RD

Report writer DATA division, REPORT section descriptor. Currently unsupported.

DATA DIVISION.
REPORT SECTION.
RD report-1
    PAGE LIMIT IS 66 LINES.

4.1.372   READ

A staple of COBOL. Read a record.

READ infile PREVIOUS RECORD INTO back-record
   AT END
       SET attop TO TRUE
   NOT AT END
       PERFORM cursor-calculator
END-READ

4.1.373   RECEIVE

An unsupported Communication Section clause.

4.1.374   RECORD

Multiple use phrase.

FD file
    RECORD IS VARYING IN SIZE FROM 1 TO 80 CHARACTERS
        DEPENDING ON size-field

SELECT file
    ASSIGN TO filename
    ACCESS MODE IS RANDOM
    RECORD KEY IS key-field
    ALTERNATE KEY IS alt-key WITH DUPLICATES.

READ infile NEXT RECORD INTO display-rec END-READ

4.1.375   RECORDING

An obsolete, recognized, but ignored file descriptor clause.

FD file
    RECORD IS VARYING IN SIZE FROM 1 TO 80 CHARACTERS
        DEPENDING ON size-field
    RECORDING MODE IS F.

4.1.376   RECORDS

Multiple use phrase.

UNLOCK file-1s RECORDS

4.1.377   RECURSIVE

Specifies a PROGRAM-ID as having the recursive attribute. Recursive sub programs can CALL themselves.

This qualifier has implications on how OpenCOBOL allocates storage. Normally storage is stacked, recursion can chew through stack space very quickly. Sub programs marked RECURSIVE are usually allocated using the memory heap.

PROGRAM-ID nextbigthing IS RECURSIVE.

4.1.378   REDEFINES

A very powerful DATA division control alllowing for redefinition of memory storage, including incompatible data by type.

IDENTIFICATION   DIVISION.
PROGRAM-ID.      prog.
DATA             DIVISION.
WORKING-STORAGE  SECTION.
01 X             PIC X.
01 G             REDEFINES X.
  02 A           PIC X.
  02 B           REDEFINES A PIC 9.
PROCEDURE        DIVISION.
    STOP RUN.

4.1.379   REEL

A tape device qualifier

CLOSE file REEL FOR REMOVAL

4.1.380   REFERENCE

The default COBOL CALL argument handler. CALL arguments can be

BY REFERENCE
BY CONTENT
BY VALUE

where by reference passes a reference pointer, allowing data modification inside sub programs.

4.1.382   RELATIVE

File organization where the position of a logical record is determined by its relative record number.

OCOBOL >>SOURCE FORMAT IS FIXED
      *> ***************************************************************
      *> Author:    Brian Tiffin
      *> Date:      20110806
      *> Purpose:   RELATIVE file organization
      *> Tectonics: cobc -g -debug -W -x relatives.cob
      *> ***************************************************************
       identification division.
       program-id. relatives.

       environment division.
       configuration section.
       repository.
           function all intrinsic.

       input-output section.
       file-control.
           select optional relatives
               assign to "relatives.dat"
               file status is filestatus
               organization is relative
               access mode is dynamic
               relative key is nicknum.

       data division.
       file section.
       fd relatives.
          01 person.
             05 firstname      pic x(48).
             05 lastname       pic x(64).
             05 relationship   pic x(32).

       working-storage section.
       77 filestatus pic 9(2).
          88 ineof value 1 when set to false is 0.

       77 satisfaction pic 9.
          88 satisfied value 1 when set to false is 0.

       77 nicknum   pic 9(2).

       77 title-line pic x(34).
          88 writing-names value "Adding, Overwriting.  00 to finish".
          88 reading-names value "Which record?         00 to quit".
       77 problem   pic x(80).

       screen section.
       01 detail-screen.
          05           line 1 column 1  from title-line erase eos.
          05           line 2 column 1  value "Record: ".
          05 pic 9(2)  line 2 column 16 using nicknum.
          05           line 3 column 1  value "First name: ".
          05 pic x(48) line 3 column 16 using firstname.
          05           line 4 column 1  value "Last name: ".
          05 pic x(64) line 4 column 16 using lastname.
          05           line 5 column 1  value "Relation: ".
          05 pic x(32) line 5 column 16 using relationship.
          05 pic x(80) line 6 column 1  from problem.

       01 show-screen.
          05           line 1 column 1  from title-line erase eos.
          05           line 2 column 1  value "Record: ".
          05 pic 9(2)  line 2 column 16 using nicknum.
          05           line 3 column 1  value "First name: ".
          05 pic x(48) line 3 column 16 from firstname.
          05           line 4 column 1  value "Last name: ".
          05 pic x(64) line 4 column 16 from lastname.
          05           line 5 column 1  value "Relation: ".
          05 pic x(32) line 5 column 16 from relationship.
          05 pic x(80) line 6 column 1  from problem.

      *> -*********-*********-*********-*********-*********-*********-**
       procedure division.
       beginning.

      *> Open the file and find the highest record number
      *> which is a sequential read operation after START
           open input relatives

           move 99 to nicknum
           start relatives key is less than or equal to nicknum
               invalid key
                   move concatenate('NO START' space filestatus)
                     to problem
                   move 00 to nicknum
               not invalid key
                   read relatives next end-read
           end-start

      *> Close and open for i-o
           close relatives
           open i-o relatives

      *> Prompt for numbers and names to add until 00
           set writing-names to true
           set satisfied to false
           perform fill-file through fill-file-end
               until satisfied

           close relatives

      *> Prompt for numbers to view names of until 00
           open input relatives

           set reading-names to true
           set satisfied to false
           perform record-request through record-request-end
               until satisfied

           perform close-shop
       .
       ending.
           goback.

      *> get some user data to add
       fill-file.
           display detail-screen end-display.
           accept detail-screen end-accept.
           move spaces to problem
           if nicknum equal 0
               set satisfied to true
               go to fill-file-end
           end-if.
       .
       write-file.
           write person
               invalid key
                   move concatenate("overwriting: " nicknum) to problem
                   rewrite person
                       invalid key
                           move concatenate(
                               exception-location() space nicknum
                               space filestatus)
                           to problem
                   end-rewrite
           end-write.
           display detail-screen end-display

       .
       fill-file-end.
       .

      *> get keys to display
       record-request.
           display show-screen end-display
           accept show-screen end-accept
           move spaces to problem
           if nicknum equals 0
               set satisfied to true
               go to record-request-end
           end-if
       .

      *> The magic of relative record number reads
       read-relation.
           read relatives
               invalid key
                   move exception-location() to problem
               not invalid key
                   move spaces to problem
           end-read
           display show-screen end-display
       .

       record-request-end.
       .

      *> get out <*
       close-shop.
           close relatives.
           goback.
       .
       end program relatives.

with sample screens:

Adding, Overwriting.  00 to finish
Record:        04
First name:    Brad____________________________________________
Last name:     Tiffin__________________________________________________________
Relation:      brother_________________________

allowing for new record additions or overwrites of existing key numbers, and:

Which record?         00 to quit
Record:        03
First name:    Brian
Last name:     Tiffin
Relation:

where typing in a nicknum record number retrieves the relative record.

4.1.383   RELEASE

Release a record to a SORT. Used with INPUT PROCEDURE of SORT verb.

RELEASE record-1 FROM identifier-1

4.1.384   REMAINDER

Access to integer remainders during division.

DIVIDE
    hex-val BY 16 GIVING left-nibble REMAINDER right-nibble
END-DIVIDE

4.1.385   REMOVAL

A close clause.

CLOSE filename-1 REEL FOR REMOVAL

Specifies that the file is stored on multiple removable tapes/disks. Not all systems support such devices.

4.1.386   RENAMES

OpenCOBOL supports regrouping of level 02-49 data items with level 66 and RENAMES.

OCOBOL >>SOURCE FORMAT IS FIXED
      *> ***************************************************************
      *> Author:    Brian Tiffin
      *> Date:      20110606
      *> Purpose:   Demonstration of 66-level datanames
      *> Tectonics: cobc
      *> ***************************************************************
       identification division.
       program-id. sixtysix.

       data division.
       working-storage section.
       01 master.
          05 field-1 pic s9(9).
          05 field-2 pic x(16).
          05 field-3 pic x(4).
          05 field-4 pic s9(9).
       66 sixtysix renames field-2.
       66 group-66 renames field-2 through field-4.

      *> ***************************************************************
       procedure division.
       move -66 to field-1
       move "sixtysix" to field-2
       move "ABCD" to field-3
       multiply field-1 by -1 giving field-4 end-multiply
       display "master  : " master end-display
       display "field-1 : " field-1 end-display
       display "sixtysix: " sixtysix end-display
       display "group-66: " group-66 end-display

       goback.
       end program sixtysix.

giving:

$ ./sixtysix
master  : 00000006vsixtysix        ABCD000000066
field-1 : -000000066
sixtysix: sixtysix
group-66: sixtysix        ABCD000000066

4.1.387   REPLACE

A COBOL text preprocessing operator.

REPLACE ==MARKER== BY ==DISPLAY "REPLACE EXAMPLE" END-DISPLAY==.
identification division.
program-id. prog.

procedure division.
MARKER
goback.
end program prog.

And then to see how that REPLACE is working, use cobc with the -E argument

# 1 "replacing.cob"

 identification division.
 program-id. prog.

 procedure division.
 DISPLAY "REPLACE EXAMPLE" END-DISPLAY
 goback.
 end program prog.

4.1.388   REPLACING

An INSPECT subclause. A COPY preprocessor clause.

4.1.389   REPORT

Unsupported Report Writer section and File descriptor clause.

4.1.390   REPORTING

Unsupported declarative for Report Writer.

4.1.391   REPORTS

Unsupported Report Writer file descriptor clause associating files with named reports.

4.1.392   REPOSITORY

A paragraph of the CONFIGURATION SECTION. OpenCOBOL supports the FUNCTION ALL INTRINSIC clause of the REPOSITORY. Allows source code to use intrinsic functions without the FUNCTION keyword.

OCOBOL >>SOURCE FORMAT IS FIXED
      *> ***************************************************************
      *> Author:    Brian Tiffin
      *> Date:      20110213
      *> Purpose:   Demonstrate an intrinstric function shortcut
      *> Tectonics: cobc -x functionall.cob
      *> ***************************************************************
       identification division.
       program-id. functionall.

       environment division.
       configuration section.
       repository.
           function all intrinsic.

      *> ***************************************************************
       procedure division.
       display function pi space function e end-display
       display pi space e end-display

       goback.
       end program functionall.

Sample output:

$ cobc -x functionall.cob
$ ./functionall
3.1415926535897932384626433832795029 2.7182818284590452353602874713526625
3.1415926535897932384626433832795029 2.7182818284590452353602874713526625

Without the repository paragraph:

$ cobc -x functionall.cob
functionall.cob:19: Error: 'pi' undefined
functionall.cob:19: Error: 'e' undefined

4.1.393   REQUIRED

Recognized but ignored Screen section field attribute.

4.1.394   RESERVE

An unsupported SELECT clause.

4.1.395   RESET

Unsupported Report Writer data control field clause.

4.1.396   RESUME

Unsupported declarative control flow statement.

4.1.397   RETRY

Unsupported record locking wait and retry clause.

  • RETRY n TIMES
  • RETRY FOR n SECONDS
  • RETRY FOREVER

4.1.398   RETURN

Return records in a SORT OUTPUT PROCEDURE.

4.1.399   RETURNING

Specify the destination of CALL results.

01 result PIC S9(8).

CALL "libfunc" RETURNING result END-CALL

Specify the return field for a sub-program.

PROCEDURE DIVISION USING thing RETURNING otherthing

4.1.400   REVERSE-VIDEO

SCREEN section field display attribute. Functionality dependent on terminal and operating system support and settings.

4.1.401   REWIND

A really cool lyric in the Black Eyed Peas song, “Hey Mama”.

4.1.402   REWRITE

Allow overwrite of records where primary key exists.

write person
    invalid key
        move concatenate("overwriting: " nicknum) to problem
        rewrite person
            invalid key
                move concatenate(
                    exception-location() space nicknum
                    space filestatus)
                to problem
        end-rewrite
end-write.

4.1.403   RF

Short form for unsupported REPORT FOOTING.

4.1.404   RH

Short form for unsupported REPORT HEADING.

4.1.406   ROLLBACK

Recognized but not fully supported revert of transactional revert of file writes. See COMMIT.

4.1.407   ROUNDED

Well defined rounding clause applied to arithmetic. Defined well enough for bank managers to feel comfortable handing their calculations over to a bunch of nerds.

COMPUTE total-value ROUNDED = 1.0 / 6.0 END-COMPUTE

4.1.408   RUN

A stopping point.

STOP RUN RETURNING 1

Terminates run regardless of nesting depth, returning control (and result) to operating system. See GOBACK and EXIT PROGRAM for other run unit terminations.

4.1.409   SAME

I-O-CONTROL clause for SAME RECORD AREA.

4.1.410   SCREEN

Screen section.

OCOBOL >>SOURCE FORMAT IS FIXED
      *> ************************************************************ <*
      *> Author:    Brian Tiffin
      *> Date:      20110701
      *> Purpose:   Play with 2.0 screen section
      *> Tectonics: cobc
      *> ************************************************************ <*
       identification division.
       program-id. screening.

       data division.
       working-storage section.
       01 some-data pic s9(9).

       screen section.
       01 detail-screen.
          03 line 1 column 1 value "title line".
          03 line 2 column 1 value "field: ".
          03 line 2 column 16 using some-data.

      *> ************************************************************ <*
       procedure division.
       display detail-screen end-display
       accept detail-screen end-accept
       goback.

       end program screening.

being a poor representation of the plethora of field attribute control allowed in OpenCOBOL screen section.

Screen field attributes include:

  • JUSTIFIED RIGHT
  • BLANK WHEN ZERO
  • OCCURS integer-val TIMES
  • BELL, BEEP
  • AUTO, AUTO-SKIP, AUTOTERMINATE
  • UNDERLINE
  • OVERLINE
  • SECURE
  • REQUIRED
  • FULL
  • PROMPT
  • REVERSE-VIDEO
  • BLANK LINE
  • BLANK SCREEN
  • ERASE EOL
  • ERASE EOS
  • SIGN IS LEADING SEPERATE CHARACTER
  • SIGN IS TRAILING SEPERATE CHARACTER
  • LINE NUMBER IS [PLUS] integer-val
  • COLUMN NUMBER IS [PLUS] integer-val
  • FOREGROUND-COLOR IS integer-val HIGHLIGHT, LOWLIGHT
  • BACKGROUND-COLOR IS integer-val BLINK
  • PICTURE IS picture-clause USING identifier
  • PICTURE IS picture-clause FROM identifier, literal
  • PICTURE IS picture-clause TO identifier
  • VALUE is literal

During ACCEPT, USING fields are read/write, FROM fields are read and TO fields are write.

See What are the OpenCOBOL SCREEN SECTION colour values? for colour values.

4.1.411   SD

SORT file data descriptor.

SD sort-file-1
    RECORD CONTAINS 80 CHARACTERS.

4.1.413   SECONDS

Clause of unsupported read/write RETRY on lock.

4.1.414   SECTION

COBOL source code is organized in DIVISION, SECTION, paragraphs and sentences. OpenCOBOL supports user named sections and recognizes the following list of pre-defined sections.

User defined sections provide for source code organization and use of PERFORM with THROUGH for tried and true COBOL procedural programming.

4.1.415   SECURE

SCREEN section field attribute. Displayed as asterisks.

4.1.416   SEGMENT

Unsupported Communication section clause.

4.1.417   SELECT

FILE-CONTROL phrase. Associates files with names, descriptors, and options.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
    SELECT fileresource
        ASSIGN TO external-name
        FILE STATUS IS identifier
        COLLATING SEQUENCE IS alphabet-name
        LOCK MODE IS MANUAL WITH LOCK ON MULTIPLE RECORDS
        RECORD DELIMITER IS STANDARD
        RESERVE num AREA
        SHARING WITH NO OTHER
        ORGANIZATION IS INDEX
            ACCESS MODE IS DYNAMIC
            RECORD KEY IS key-field
            ALTERNATE RECORD KEY IS key-field-2 WITH DUPLICATES
            ALTERNATE RECORD KEY IS key-field-3.

though, naming a quick file can be as simple as

SELECT myfile ASSIGN TO "name.txt".

which will be a default LINE SEQUENTIAL file.

4.1.418   SELF

Unsupported Object COBOL clause.

4.1.419   SEND

Unsupported Communication section verb.

4.1.420   SENTENCE

An obsolete control flow clause. CONTINUE is preferred to NEXT SENTENCE.

4.1.421   SEPARATE

Fine tuned control over leading and trailing sign indicator.

77 field-1 PICTURE S9(8) SIGN IS TRAILING SEPARATE.

4.1.422   SEQUENCE

Controls COLLATING sequence for character compares, by defining a character set.

4.1.423   SEQUENTIAL

OpenCOBOL supports both fixed length SEQUENTIAL and newline terminated LINE SEQUENTIAL file access.

4.1.424   SET

  • SET ADDRESS OF ptr-var TO var.
  • SET ENVIRONMENT “name” TO “value”.
  • SET cond-1 TO TRUE

That last one is pretty cool. An 88 level conditional set TRUE will cause the associated value to change to a value that satifies the condition as true.

01 field-1 pic 99.
   88 cond-1 value 42.

MOVE 0 TO field-1
DISPLAY field-1 END-DISPLAY
SET cond-1 TO TRUE
DISPLAY field-1 END-DISPLAY

00 and 42 are displayed.

4.1.425   SHARING

File sharing option.

  • SHARING WITH NO OTHER
  • SHARING WITH ALL OTHER
  • SHARING WITH READ ONLY

Functionality dependent on build options and operating system running OpenCOBOL.

4.1.426   SIGN

Fine tuned control over leading and trailing sign indicator.

77 field-1 PICTURE S9(8) SIGN IS TRAILING SEPARATE.

4.1.427   SIGNED

OpenCOBOL supports the full gamut of COBOL numeric data storage. SIGNED and UNSIGNED being part and parcel.

4.1.428   SIGNED-INT

A native storage format NUMERIC data USAGE clause. Equivalent to BINARY-LONG, BINARY-LONG SIGNED, and SIGNED-LONG.

4.1.429   SIGNED-LONG

A native storage format NUMERIC data USAGE clause. Equivalent to BINARY-LONG, BINARY-LONG SIGNED, and SIGNED-INT.

4.1.430   SIGNED-SHORT

A native storage format NUMERIC data USAGE clause. Equivalent to BINARY-SHORT SIGNED.

4.1.431   SIZE

Multi purpose.

OpenCOBOL allows SIZE IS control on CALL arguments.

Arthimetic operations allow for declaritives on size errors.

ADD 1 TO ocobol
    ON SIZE ERROR
        SET erroneous TO TRUE
    NOT ON SIZE ERROR
        DISPLAY "Whee, ADD 1 TO COBOL" END-DISPLAY
END-ADD

STRING has a DELIMITED BY SIZE option to include entire fields.

4.1.432   SORT

OpenCOBOL supports USING, GIVING as well as INPUT PROCEDURE and OUTPUT PROCEDURE clauses for the SORT verb.

OCOBOL* OpenCOBOL SORT verb example using standard in and standard out
       identification division.
       program-id. sorting.

       environment division.
       input-output section.
       file-control.
           select sort-in
               assign keyboard
               organization line sequential.
           select sort-out
               assign display
               organization line sequential.
           select sort-work
               assign "sortwork".

       data division.
       file section.
       fd sort-in.
          01 in-rec        pic x(255).
       fd sort-out.
          01 out-rec       pic x(255).
       sd sort-work.
          01 work-rec      pic x(255).

       procedure division.
       sort sort-work
           ascending key work-rec
           using  sort-in
           giving sort-out.

       goback.
       exit program.
       end program sorting.

In the next sample, demonstrating INPUT PROCEDURE and OUTPUT PROCEDURE take note of the RETURN and RELEASE verbs as they are key to record by record control over sort operations.

Also, just to complicate things, this sample sorts using a mixed-case alphabet (but also places capital A out of order to demonstrate special cases that can codified in an ALPHABET).

OCOBOL >>SOURCE FORMAT IS FIXED
      ******************************************************************
      * Author:    Brian Tiffin
      * Date:      02-Sep-2008
      * Purpose:   An OpenCOBOL SORT verb example
      * Tectonics: cobc -x sorting.cob
      *     ./sorting <input >output
      *   or simply
      *     ./sorting
      *   for keyboard and screen demos
      ******************************************************************
       identification division.
       program-id. sorting.

       environment division.
       configuration section.
      * This sets up a sort order lower then upper except for A and a
       special-names.
           alphabet mixed is " AabBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTu
      -"UvVwWxXyYzZ0123456789".

       input-output section.
       file-control.
           select sort-in
               assign keyboard
               organization is line sequential.
           select sort-out
               assign display
               organization is line sequential.
           select sort-work
               assign "sortwork".

       data division.
       file section.
       fd sort-in.
          01 in-rec        pic x(255).
       fd sort-out.
          01 out-rec       pic x(255).
       sd sort-work.
          01 work-rec      pic x(255).

       working-storage section.
       01 loop-flag        pic x value low-value.

       procedure division.
       sort sort-work
           on descending key work-rec
           collating sequence is mixed
           input procedure is sort-transform
           output procedure is output-uppercase.

       display sort-return end-display.
       goback.

      ******************************************************************
       sort-transform.
       move low-value to loop-flag
       open input sort-in
       read sort-in
           at end move high-value to loop-flag
       end-read
       perform
           until loop-flag = high-value
               move FUNCTION LOWER-CASE(in-rec) to work-rec
               release work-rec
               read sort-in
                   at end move high-value to loop-flag
               end-read
       end-perform
       close sort-in
       .

      ******************************************************************
       output-uppercase.
       move low-value to loop-flag
       open output sort-out
       return sort-work
           at end move high-value to loop-flag
       end-return
       perform
           until loop-flag = high-value
               move FUNCTION UPPER-CASE(work-rec) to out-rec
               write out-rec end-write
               return sort-work
                   at end move high-value to loop-flag
               end-return
       end-perform
       close sort-out
       .

       exit program.
       end program sorting.

Here is a snippet describing TABLE sorts by [jrls_swla]

table define

    01  nbr-of-columns  pic 9(4) value zero.
    01  tcindex2        usage is index.
    01  dbtables.
        03  tables-columns  occurs 1 to 1000 times
                depending on nbr-of-columns
                ascending key tcTable, tcColumn
                            indexed by tcindex.
        05  tcTable     pic x(64)   value spaces.
        05  tcColumn    pic x(64)   value spaces.
            05  tcAlias pic x(10)   value spaces.
        05  tcOrder pic 9(4)    value zero.
            05  tcType  pic x(10)   value spaces.
            05  tcMaxLen    pic 9(4)    value zero.
    *><*
    01  aliasName.
        05          pic x value "t".
        05 anVal        pic 9(3)    value zero.

     01 showdata.
        05  sdTable     pic x(17) value spaces.
        05  sdColumn    pic x(17) value spaces.
        05  sdType      pic x(10) value spaces.
        05  sdOrder     pic zzzzz-.
        05  sdMaxLen    pic zzzzz.

table load

   perform varying rows from 1 by 1
       until rows > dbNumRows
       call "dbNextRow"     using by value dbResult,
                                  by reference ColumnBuff,
                                  by reference CbuffDesc
            returning dbResult
       add 1            to nbr-of-columns
       set tcindex          up by 1
       move cbTable         to tcTable(tcindex)
       move cbColumn        to tcColumn(tcindex)
       move cbType          to tcType(tcindex)
       move cbOrder         to tcOrder(tcindex)
       move cbMaxLen        to tcMaxLen(tcindex)
       if nbr-of-columns = 1
          add 1         to anVal
       else
          set tcindex2      to tcindex
          set tcindex2      down by 1
          if cbTable <> tcTable(tcindex2)
             add 1          to anVal
          end-if
       end-if
       move aliasName       to tcAlias(tcindex)
   end-perform.


table sort

    sort tables-columns ascending key tcTable, tcColumn.

display table

    perform varying tcindex from 1 by 1
        until tcindex > nbr-of-columns
        move tcTable(tcindex)       to sdTable
        move tcColumn(tcindex)      to sdColumn
        move tcOrder(tcindex)       to sdOrder
        move tcType(tcindex)        to sdType
        move tcMaxLen(tcindex)      to sdMaxLen
        display showdata
    end-perform.

Excercise for the audience. Could the above code be simplified by using

MOVE CORRESPONDING cbRecord to table-columns(tcindex)
...
MOVE CORRESPONDING table-columns(tcindex) to showdata

with a few judicious field name changes?

4.1.432.1   An OCSORT support tool

There is an external sort utility referenced in What is ocsort?

4.1.433   SORT-MERGE

Used in an I-O-CONTROL paragraph with the SAME clause:

SAME SORT-MERGE AREA FOR filename-1.

The SORT-MERGE keyword and SORT keyword are equivalent in this case.

4.1.434   SORT-RETURN

A SPECIAL-REGISTER used by the OpenCOBOL SORT routines.

  • +000000000 for success
  • +000000016 for failure

A programmer may set SORT-RETURN in an INPUT PROCEDURE.

4.1.435   SOURCE

Compiler directive controlling source code handling.

>>SOURCE FORMAT IS FIXED
>>SOURCE FORMAT IS FREE

OpenCOBOL allows use of this directive at programmer whim. cobc defaults to FIXED format source handling, so the directive must occur beyond the sequence and indicator columns unless the -free compile option is used.

Split keys are a pending feature in OpenCOBOL.

SELECT ...
    RECORD KEY IS key-name SOURCE is dname-2 dname-3

Also a pending Report Writer data source clause.

4.1.436   SOURCE-COMPUTER

A paragraph of the IDENTIFICATION division. Treated as a comment.

4.1.437   SOURCES

Currently unsupported SOURCES ARE report writer clause.

4.1.438   SPACE

A figurative constant representing a space character.

4.1.439   SPACES

A figurative constant representing space characters.

4.1.440   SPECIAL-NAMES

OpenCOBOL supports a fair complete set of the SPECIAL-NAMES in common use.

  • CONSOLE IS CRT
  • SYSIN IS mnemonic-name-1
  • SYSOUT IS
  • SYSLIST IS
  • SYSLST IS
  • PRINTER IS
  • SYSERR IS
  • CONSOLE IS mnemonic-name-7
  • SWITCH-1 IS mnemonic-name-n ON STATUS IS condition-name-1 OFF STATUS IS condition-name-2
  • SWITCH-2
  • ...
  • SWITCH-8 IS ...
  • C01 IS mnemonic-name-m
  • ...
  • C12 IS
  • ALPHABET alphabet-name IS NATIVE, STANDARD-1, STANDARD-2, EBCDIC literal-1 THRU literal-2 [ALSO literal-3]
  • SYMBOLIC CHARACTERS symbol-character IS integer-1 IN alphabet-name
  • CLASS class-name IS literal THRU literal-2
  • LOCALE locale-name IS identifier-1
  • CURRENCY SIGN IS literal
  • DECIMAL-POINT IS COMMA
  • CURSOR IS identifier-1
  • CRT STATUS IS identifier-1
  • SCREEN CONTROL IS identifier-1 PENDING
  • EVENT STATUS IS identifier-1 PENDING

4.1.441   STANDARD

  • LABEL RECORDS ARE STANDARD

4.1.442   STANDARD-1

  • ALPHABET IS STANDARD-1
  • RECORD DELIMITER IS STANDARD-1

equivalent to ASCII

4.1.443   STANDARD-2

  • ALPHABET IS STANDARD-1
  • RECORD DELIMITER IS STANDARD-1

equivalent to ASCII

4.1.444   START

Sets internal file fields that will influence sequential READ NEXT and READ PREVIOUS for INDEXED files. Can also be used to seek to the FIRST or LAST record of a file for SEQUENTIAL access modes.

start indexing
   key is less than
       keyfield of indexing-record
   invalid key
       display
           "bad start: " keyfield of indexing-record
       end-display
       set no-more-records to true
   not invalid key
       read indexing previous record
           at end set no-more-records to true
       end-read
end-start

The conditionals are quite powerful.

KEY IS GREATER THAN
KEY IS >
KEY IS LESS THAN
KEY IS <
KEY IS EQUAL TO
KEY IS =

KEY IS NOT GREATER THAN
KEY IS NOT >
KEY IS NOT LESS THAN
KEY IS NOT <
KEY IS NOT EQUAL TO
KEY IS NOT =

KEY IS <>
KEY IS GREATER THAN OR EQUAL TO
KEY IS >=
KEY IS LESS THAN OR EQUAL TO
KEY IS <=

See Does OpenCOBOL support ISAM? for some example source code.

4.1.446   STATUS

Multi-purpose.

  • CRT STATUS IS
  • FILE STATUS IS
  • EVENT STATUS IS
  • SWITCH-1 IS thing ON STATUS IS conditional-1

4.1.447   STEP

Unsupported Report Writer OCCURS subclause.

4.1.448   STOP

End a run and return control to the operating system.

STOP RUN RETURNING 5.

Forms include:

  • STOP RUN
  • STOP RUN RETURNING stat
  • STOP RUN GIVING stat
  • STOP literal
  • STOP RUN WITH ERROR STATUS stat
  • STOP RUN WITH NORMAL STATUS stat

4.1.449   STRING

String together a set of variables with controlled delimiters.

01 var PICTURE X(5).

STRING
   "abc" DELIMITED BY "b"
   "def" DELIMITED BY SIZE
   "ghi" DELIMITED BY "z"
   INTO var
   ON OVERFLOW
       DISPLAY "var is full at" SPACE LENGTH OF var END-DISPLAY
END-STRING

DISPLAY var END-DISPLAY

Outputs:

var is full at 5
adefg

OpenCOBOL also fully supports the WITH POINTER clause to set the initial and track the position in the output character variable.

4.1.450   STRONG

Unsupported.

4.1.451   SUB-QUEUE-1

Unsupported Communication section clause.

4.1.452   SUB-QUEUE-2

Unsupported Communication section clause.

4.1.453   SUB-QUEUE-3

Unsupported Communication section clause.

4.1.454   SUBTRACT

Arithmetic operation.

SUBTRACT a b c FROM d ROUNDED END-SUBTRACT

SUBTRACT a FROM b GIVING c
    ON SIZE ERROR
        SET math-error TO TRUE
    NOT ON SIZE ERROR
        SET math-error TO FALSE
END-SUBTRACT

SUBTRACT CORRESPONDING record-a FROM record-b ROUNDED
    ON SIZE ERROR
        SET something-wrong TO TRUE
END-SUBTRACT

4.1.455   SUM

A REPORT SECTION control break summation field clause. Unsupported.

4.1.456   SUPER

Unsupported Object COBOL clause.

4.1.457   SUPPRESS

Unsupported declarative to suppress printing.

4.1.458   SYMBOL

Unsupported.

4.1.459   SYMBOLIC

SPECIAL-NAMES clause allowing user defined figurative constants.

4.1.461   SYNCHRONIZED

Control padding inside record definitions, in particular to match C structures.

01 infile.
   03 slice    occurs 64 times depending on slices.
      05 stext usage pointer synchronized.
      05 val   float-long    synchronized.
      05 ftext usage pointer synchronized.

4.1.462   SYSTEM-DEFAULT

OBJECT-COMPUTER clause for locale support.

CHARACTER CLASSIFICATION IS SYSTEM-DEFAULT

4.1.463   TABLE

Unsupported keyword, but OpenCOBOL fully supports tables, including SORT.

4.1.464   TALLYING

INSPECT clause for counting occurances of a literal.

INSPECT record-1 TALLYING ident-1 FOR LEADING "0"

4.1.465   TAPE

A device type used in ASSIGN.

4.1.466   TERMINAL

Unsupported Comminication section clause.

4.1.467   TERMINATE

Currently unsupported Report Writer verb to finish up a report. See INITIATE.

4.1.468   TEST

Allows control over when loop conditionals are tested. WITH TEST BEFORE is the default. WITH TEST AFTER will always evaluate the body of the loop at least once.

perform
    with test after
    varying x from 1 by xstep
    until x >= function e
        if x > function e
            move function e to x-value
        else
            move x to x-value
        end-if
        compute recip = 1 / x end-compute
        move recip to y-value
        write outrec end-write
end-perform

4.1.469   TEXT

Unsupported Communication section clause.

4.1.470   THAN

Part of the conditional clauses for readability.

IF A GREATER THAN 10
    DISPLAY "A > 10" END-DISPLAY
END-IF

4.1.471   THEN

A somewhat disdained keyword that is part of the IF THEN ELSE control structure.

IF A > 10 THEN
   DISPLAY "A GREATER THAN 10" END-DISPLAY
ELSE
   DISPLAY "A LESS THAN OR EQUAL TO 10" END-DISPLAY
END-IF

4.1.472   THROUGH

Used in definitions for alphabets in SPECIAL-NAMES and a procedural clause allowing PERFORM from one label THROUGH (inclusive) to another label and all paragraphs in between. Also used to specify grouping with RENAMES.

PERFORM 100-open-files THROUGH 100-files-end

4.1.473   THRU

Commonly used alias for THROUGH

4.1.474   TIME

An ACCEPT FROM source. Allows access to current clock.

01 current-time.
   05 ct-hours      pic 99.
   05 ct-minutes    pic 99.
   05 ct-seconds    pic 99.
   05 ct-hundredths pic 99.

ACCEPT current-time FROM TIME

4.1.475   TIMES

A counted loop.

PEFORM 5 TIMES
    DISPLAY "DERP" END-DISPLAY
END-PERFORM

4.1.476   TO

Multi-purpose destination specifier.

ADD 1 TO cobol GIVING OpenCOBOL
    ON SIZE ERROR
        DISPLAY "Potential exceeds expectations" END-DISPLAY
END-ADD

4.1.478   TRAILING

Multi-purpose. FUNCTION TRIM allows a TRAILING keyword. An INSPECT TALLYING subclause.

4.1.479   TRUE

A SET target. Used in EVALUATE to control when the operation succeeds. When used with a conditional 88 level name, will set the corresponding field to a listed VALUE.

01 field-1 pic x.
   88 cond-1 values 'a','b','c'.

SET cond-1 TO TRUE
DISPLAY field-1 END-DISPLAY

4.1.480   TYPE

An unsupported Report Writer report group clause. Also unsupported data description clause.

4.1.481   TYPEDEF

Unsupported data description clause that will allow user defined record layouts.

4.1.482   UCS-4

Currently unsupported Universal Character Set alphabet. UCS-4 would store international code points in 4 bytes.

4.1.483   UNDERLINE

SCREEN section field attribute.

4.1.484   UNIT

A close option, alias for REEL.

CLOSE file-1 UNIT WITH NO REWIND

4.1.485   UNIVERSAL

Unsupported Object COBOL exception object clause.

4.1.486   UNLOCK

Manual record unlock and buffer write sync.

UNLOCK filename-1 RECORDS

4.1.487   UNSIGNED

Usage clause specifing that a value will not include any sign and therefore can’t be negative.

4.1.488   UNSIGNED-INT

A native storage format NUMERIC data USAGE clause. Equivalent to BINARY-LONG UNSIGNED and UNSIGNED-LONG.

4.1.489   UNSIGNED-LONG

A native storage format NUMERIC data USAGE clause. Equivalent to BINARY-LONG UNSIGNED and UNSIGNED-INT.

4.1.490   UNSIGNED-SHORT

A native storage format NUMERIC data USAGE clause. Equivalent to BINARY-SHORT UNSIGNED and UNSIGNED-SHORT.

4.1.491   UNSTRING

A powerful string decomposition verb.

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
    WITH POINTER ptr-1
    ON OVERFLOW
        SET more-fields TO TRUE
END-UNSTRING

4.1.492   UNTIL

Sets a loop conditional.

PERFORM VARYING ident-1 FROM 1 BY 1 UNTIL ident-1 > 10
    CALL "thing" USING BY VALUE ident-1 END-CALL
END-PERFORM

4.1.493   UP

Index and pointer modification.

SET ptr-1 UP BY 4
SET ind-1 UP BY 1

4.1.494   UPDATE

SCREEN section field attribute.

4.1.495   UPON

A DISPLAY destination clause.

4.1.496   USAGE

OpenCOBOL uses standard big-endian internal storage by default. USAGE clauses influence the data representation. The INTEL architecture uses little-endian form and OpenCOBOL programmers developing for this common chipset may need to pay heed to this for performance purposes. As per the standards, OpenCOBOL supports COMPUTATIONAL-5 native usage.

OpenCOBOL enables use of one to eight byte binary representations in both big and little endian forms.

Along with full support of all common COBOL PICTURE clauses both storage and display, OpenCOBOL supports USAGE clauses of:

  • BINARY
  • COMPUTATIONAL, COMP
  • COMP-1
  • COMP-2
  • COMP-3
  • COMP-4
  • COMP-5
  • COMP-X
  • FLOAT-LONG
  • FLOAT-SHORT
  • DISPLAY
  • INDEX
  • PACKED-DECIMAL
  • POINTER
  • PROGRAM-POINTER
  • SIGNED-SHORT
  • SIGNED-INT
  • SIGNED-LONG
  • UNSIGNED-SHORT
  • UNSIGNED-INT
  • UNSIGNED-LONG
  • BINARY-CHAR SIGNED
  • BINARY-CHAR UNSIGNED
  • BINARY-CHAR
  • BINARY-SHORT SIGNED
  • BINARY-SHORT UNSIGNED
  • BINARY-SHORT
  • BINARY-LONG SIGNED
  • BINARY-LONG UNSIGNED
  • BINARY-LONG
  • BINARY-DOUBLE SIGNED
  • BINARY-DOUBLE UNSIGNED
  • BINARY-DOUBLE
  • BINARY-C-LONG SIGNED
  • BINARY-C-LONG UNSIGNED
  • BINARY-C-LONG

4.1.497   USE

Sets up DECLARATIVES paragraphs.

  • USE BEFORE DEBUGGING
  • USE AFTER EXECEPTION

4.1.498   USER-DEFAULT

OBJECT-COMPUTER clause for locale support.

CHARACTER CLASSIFICATION IS USER-DEFAULT

4.1.499   USING

Specifies arguments to CALL and in PROCEDURE declarations.

  • BY REFERENCE (default, pointer to modifiable data is passed)
  • BY CONTENT (reference to a copy of the data)
  • BY VALUE (actual dereferenced value is placed into call frame)

4.1.500   UTF-16

Unsupported internationalization clause.

4.1.501   UTF-8

Unsupported internationalization clause.

4.1.502   VAL-STATUS

Alias for the unsupported VALIDATE-STATUS clause of the VALIDATE statement.

4.1.503   VALID

Unsupported.

4.1.504   VALIDATE

Unsupported data validation verb.

4.1.505   VALIDATE-STATUS

Unsupported clause of the VALIDATE statement.

4.1.506   VALUE

An CALL frame argument modifier. Sets values in data descriptions as well as values used with 88 level conditional names.

4.1.507   VALUES

Plural of VALUE when more than one entry is used in an 88 conditional name.

4.1.508   VARYING

Sets a looping variable.

PERFORM VARYING loop-counter FROM 1 BY 1 UNTIL loop-counter > 10
    DISPLAY loop-counter END-DISPLAY
END-PERFORM

4.1.509   WHEN

A very powerful keyword used in EVALUATE phrases for specifying conditional expressions.

EVALUATE TRUE
    WHEN A = 10
        DISPLAY "A = 10" END-DISPLAY
    WHEN A = 15
        PERFORM A-IS-15
    WHEN B IS EQUAL 6
        PERFORM B-IS-6
    WHEN C IS GREATER THAN 5
        DISPLAY "C > 5" END-DISPLAY
    WHEN OTHER
        DISPLAY "Default imperative" END-DISPLAY
 END-EVALUATE

4.1.510   WITH

Multi-purpose.

  • WITH LOCK
  • DISPLAY WITH screen-attribute
  • WITH ROLLBACK (pending)

4.1.511   WORKING-STORAGE

A DATA division section. Unless BASED, all fields are allocated and fixed in memory (for the running program within a module).

4.1.512   WRITE

Record write. Unlike READ that uses filenames syntax, WRITE uses record buffer syntax which must be related to the file through the FD file descriptor. OpenCOBOL supports LINAGE and WRITE has support for ‘report’ paging and line control.

WRITE record-buff END-WRITE

WRITE record-name-1 AFTER ADVANCING PAGE END-WRITE.

WRITE record-name-1
    AT END-OF-PAGE
        DISPLAY "EOP" END-DISPLAY
END-WRITE

4.1.513   YYYYDDD

Modifies ACCEPT var FROM DAY to use full 4 digit year for the Julian date retrieval.

ACCEPT date-var FROM DAY YYYYDDD

4.1.514   YYYYMMDD

Modifies ACCEPT var FROM DATE to use full 4 digit year.

ACCEPT date-var FROM DATE YYYYMMDD

4.1.515   ZERO

Figurative and numeric constant for the value 0.

4.1.517   ZEROS

Alternate spelling for ZEROES.

4.2   Does OpenCOBOL implement any Intrinsic FUNCTIONs?

Yes, many. As of the July 2008 1.1 pre-release

ABS, ACOS, ANNUITY, ASIN, ATAN, BYTE-LENGTH, CHAR, CONCATENATE, COS,
CURRENT-DATE, DATE-OF-INTEGER, DATE-TO-YYYYMMDD, DAY-OF-INTEGER,
DAY-TO-YYYYDDD, E, EXCEPTION-FILE, EXCEPTION-LOCATION, EXCEPTION-STATEMENT,
EXCEPTION-STATUS, EXP, EXP10, FACTORIAL, FRACTION-PART, INTEGER,
INTEGER-OF-DATE, INTEGER-OF-DAY, INTEGER-PART, LENGTH, LOCALE-DATE,
LOCALE-TIME, LOG, LOG10, LOWER-CASE, MAX, MEAN, MEDIAN, MIDRANGE, MIN, MOD,
NUMVAL, NUMVAL-C, ORD, ORD-MAX, ORD-MIN, PI, PRESENT-VALUE, RANDOM, RANGE, REM,
REVERSE, SECONDS-FROM-FORMATTED-TIME, SECONDS-PAST-MIDNIGHT, SIGN, SIN, SQRT,
STANDARD-DEVIATION, STORED-CHAR-LENGTH, SUBSTITUTE, SUBSTITUTE-CASE, SUM, TAN,
TEST-DATE-YYYYMMDD, TEST-DAY-YYYYDDD, TRIM, UPPER-CASE, VARIANCE,
WHEN-COMPILED, YEAR-TO-YYYY

4.2.1   FUNCTION ABS

Absolute value of numeric argument

DISPLAY FUNCTION ABS(DIFFERENCE).

4.2.2   FUNCTION ACOS

The ACOS function returns a numeric value (in radians) that approximates the arccosine of the argument.

The domain of the arccosine function is -1 to +1. Domain errors return a result of 0. The inverse cosine function returns a range of 0 thru π

DISPLAY FUNCTION ACOS(-1).

4.2.3   FUNCTION ANNUITY

Compute the ratio of an annuity paid based on arguments of interest and number of periods.

WORKING-STORAGE SECTION.
77  INTEREST       PIC S9V9999 VALUE 0.08.
77  MONTHLY        PIC S9V9999 VALUE ZERO.
77  PERIODS        PIC 99      VALUE 36.
77  ANNUITY-VALUE  PIC S9V9999 VALUE ZERO.
PROCEDURE DIVISION.
   COMPUTE MONTHLY ROUNDED = INTEREST / 12
   COMPUTE ANNUITY-VALUE ROUNDED =
       FUNCTION ANNUITY (MONTHLY PERIODS)
   DISPLAY "Monthly rate: " MONTHLY
       " Periods: " PERIODS
       " Annuity ratio: " ANNUITY-VALUE
   END-DISPLAY.

Outputs:

Monthly rate: +0.0067 Periods: 36 Annuity ratio: +0.0314

4.2.4   FUNCTION ASIN

The ASIN function returns a numeric value (in radians) that approximates the arcsine of the argument.

The domain of the arcsine function is -1 to +1. Domain errors return a result of 0. The inverse sine function returns a range of -π/2 thru π/2

DISPLAY FUNCTION ASIN(-1).

4.2.5   FUNCTION ATAN

The ATAN function returns a numeric value (in radians) that approximates the arctangent of the argument.

The domain of the arctangent function is all real numbers. The inverse tangent function returns a range of -π/2 thru π/2

DISPLAY FUNCTION ATAN(1).

4.2.6   FUNCTION BYTE-LENGTH

The BYTE-LENGTH function returns an integer that is the internal storage length of the given argument.

COBOL  >>SOURCE FORMAT IS FIXED
      ******************************************************************
      * Purpose:   demonstrate intrinsic FUNCTION BYTE-LENGTH
      ******************************************************************
       identification division.
       program-id. bytelength.

       data division.
       working-storage section.
       01 char-var           usage binary-char.
       01 short-var          usage binary-short.
       01 long-var           usage binary-long.
       01 double-var         usage binary-double.

       01 num1-var           pic 9.
       01 num4-var           pic 99v99.
       01 num9-var           pic s9(9).
       01 num18-var          pic s9(18).
       01 num18c-var         pic s9(18) usage comp.
       01 num18p-var         pic s9(18) usage comp-3.
       01 edit-var           pic $zzzz9.99.

       01 string-var         pic x(10) value "abc".

       01 newline            pic x value x'0a'.

       procedure division.
       display
           "num1-var   len = " function byte-length(num1-var) newline
           "num4-var   len = " function byte-length(num4-var) newline
           "num9-var   len = " function byte-length(num9-var) newline
           "num18-var  len = " function byte-length(num18-var) newline
           "num18c-var len = " function byte-length(num18c-var) newline
           "num18p-var len = " function byte-length(num18p-var) newline
           "edit-var   len = " function byte-length(edit-var) newline

           "12         len = " function byte-length(12) newline
           "12.12      len = " function byte-length(12.12) newline
           "1234567890.123 = " function
               byte-length(1234567890.123) newline

           "string-var len = " function byte-length(string-var) newline
           "trim string    = " function
               byte-length(function trim(string-var)) newline

           "char-var   len = " function byte-length(char-var) newline
           "short-var  len = " function byte-length(short-var) newline
           "long-var   len = " function byte-length(long-var) newline
           "double-var len = " function byte-length(double-var)

       end-display
       goback.
       exit program.

Outputs:

num1-var   len = 1
num4-var   len = 4
num9-var   len = 9
num18-var  len = 18
num18c-var len = 8
num18p-var len = 10
edit-var   len = 9
12         len = 2
12.12      len = 4
1234567890.123 = 13
string-var len = 10
trim string    = 00000003
char-var   len = 1
short-var  len = 2
long-var   len = 4
double-var len = 8

4.2.7   FUNCTION CHAR

The CHAR function returns a ONE character alphanumeric field whose value is the character in the current collating sequence having the ordinal position equal to the value of the integer argument. The argument must be greater than 0 and less than or equal to the number of positions in the collating sequence. Errors in the argument range return 0 (the LOW-VALUE by default).

See ASCII or EBCDIC and details of the ALPHABET clause.

DISPLAY FUNCTION CHAR(66).

Would output A in the ASCII character set. Note this may be different than what some expect. OpenCOBOL CHAR is 1 thru 128 not 0 thru 127 as a C programmer may be used to.

And to add a little confusion, most personal computers use an extended character set, usually erroneously called ASCII with a range of 0 to 255. A more appropriate name may be ISO-8859-1 Latin 1. See ASCII for more accurate details. This author is often guilty of this misnomer of the use of the term ASCII.

4.2.8   FUNCTION COMBINED-DATETIME

Returns a common datetime form from integer date (years and days from 1600 to 10000) and numeric time arguments (seconds in day). Date should be from 1 to 3067671 and time should be from 1 to 86400. The character string returned is in the form 7.5.

DISPLAY FUNCTION COMBINED-DATETIME(1; 1) END-DISPLAY

Outputs:

0000001.00001

4.2.9   FUNCTION CONCATENATE

Concatenate the given fields. CONCATENATE is an OpenCOBOL extension.

MOVE "COBOL" TO stringvar
MOVE FUNCTION CONCATENATE("Open"; stringvar) TO goodsystem
DISPLAY goodsystem END-DISPLAY

4.2.10   FUNCTION COS

The COS function returns a numeric value that approximates the cosine of the argument (in radians).

The domain of the cosine function is all real numbers, with a nominal domain of 0 thru π with a zero returned at π/2. The cosine function returns a range of -1 thru +1.

DISPLAY FUNCTION COS(1.5707963267949).

4.2.11   FUNCTION CURRENT-DATE

Returns an alphanumeric field of length 21 with the current date, time and timezone information in the form YYYYMMDDhhmmsscc±tznn

DISPLAY FUNCTION CURRENT-DATE.

Example Output:

2008080921243796-0400

4.2.12   FUNCTION DATE-OF-INTEGER

Converts an integer date, days on the Gregorian since December 31 1600 to YYYYMMDD form

DISPLAY DATE-OF-INTEGER(1)
DISPLAY DATE-OF-INTEGER(50000)

Outputs:

16010101
17371123

50,000 days after December 31, 1600 being November 23rd, 1737.

4.2.13   FUNCTION DATE-TO-YYYYMMDD

Converts a two digit year date format to four digit year form using a sliding window pivot of the optional second argument. The pivot defaults to 50.

The OpenCOBOL implementation of DATE-TO-YYYYMMDD also accepts an optional third argument, replacing the default century value of 1900 and is treated as the years added to the given year portion of the first argument and modified by the sliding 100 window pivot.

Domain errors occur for year values less than 1600 and greater than 999,999. There is no validation of the input date.

Because of the sliding window, this function is dependent on the date of evaluation

DISPLAY FUNCTION DATE-TO-YYYYMMDD(000101)
DISPLAY FUNCTION DATE-TO-YYYYMMDD(500101)
DISPLAY FUNCTION DATE-TO-YYYYMMDD(610101)
DISPLAY FUNCTION DATE-TO-YYYYMMDD(990101)

DISPLAY FUNCTION DATE-TO-YYYYMMDD(990101, 50, 1900)
DISPLAY FUNCTION DATE-TO-YYYYMMDD(990101, -10, 1900)
DISPLAY FUNCTION DATE-TO-YYYYMMDD(990101, 50, 2000)
DISPLAY FUNCTION DATE-TO-YYYYMMDD(990101, 50, 2100)

When run in August, 2008 produces:

20000101
20500101
19610101
19990101
18990101
17990101
19990101
20990101

4.2.14   FUNCTION DAY-OF-INTEGER

Converts a Gregorian integer date form to Julian date form (YYYDDD) based on days since December 31, 1600. Errors return 0

DISPLAY FUNCTION DAY-OF-INTEGER(97336).
1867182

97,336 days after 16001231 being the 182nd day of the year 1867. Canada’s date of Confederation and recognized birthday.

4.2.15   FUNCTION DAY-TO-YYYYDDD

Converts a Julian 2 digit year and three digit dat integer to a four digit year form. See FUNCTION DATE-TO-YYYYMMDD for some of the details of the calculations involved.

4.2.16   FUNCTION E

Returns Euler’s number as an alphanumeric field to 34 digits of accuracy after the decimal. E forms the base of the natural logarithms. It has very unique and important properies such as:

  • the derivative of ex is ex
  • and the area below the curve of y = 1/x for 1 <= x <= e is exactly 1.
  • making it very useful in calculations of Future Value with compound interest.
DISPLAY FUNCTION E END-DISPLAY

outputs:

2.7182818284590452353602874713526625

A small graph to show the magic area.

OCOBOL >>SOURCE FORMAT IS FIXED
      *> ***************************************************************
      *> Author:    Brian Tiffin
      *> Date:      29-May-2009, Modified 20110505 to add e tic mark
      *> Purpose:   Plot Euler's number (using integral of 1 over x)
      *> Tectonics: requires access to gnuplot. http://www.gnuplot.info
      *>            cobc -Wall -x ploteuler.cob
      *> OVERWRITES ocgenplot.gp, ocgpdata.txt and images/euler.png
      *> ***************************************************************
       identification division.
       program-id. ploteuler.

       environment division.
       input-output section.
       file-control.
           select scriptfile
               assign to "ocgenplot.gp"
               organization is line sequential.
           select outfile
               assign to "ocgpdata.txt"
               organization is line sequential.

       data division.
       file section.
       fd scriptfile.
          01 gnuplot-command pic x(82).

       fd outfile.
          01 outrec.
             03 x-value   pic -z9.999.
             03 filler    pic x.
             03 y-value   pic -z9.999.

       working-storage section.
       01 xstep   pic 9v99999.
       01 x       pic 9v99999.
       01 recip   pic 9v99999.

      *> The plot command is xrange 0:3, y 0:2 data col 1 for x 2 for y
       01 gpcmds  pic x(400) value is
           "set style fill solid 1.0;                         " &
           "set grid;                                         " &
           "set xtics add ('e' 2.718281);                     " &
           "plot [0:3] [0:2] 'ocgpdata.txt' using 1:2 \       " &
           " with filledcurves below x1  title '1/x';         " &
           "set terminal png;                                 " &
           "set output 'images/euler.png';                    " &
           "replot                                            ".
       01 line-cnt pic 999.
       01 gptable.
          05 gpcmd pic x(50) occurs 8 times.

       01 gplot   pic x(40) value is 'gnuplot -persist ocgenplot.gp'.
       01 result  pic s9(9).

      *> ***************************************************************
       procedure division.
       display function e end-display

      *><* Create the script to plot the area of Euler's number
       open output scriptfile.
       move gpcmds to gptable
       perform varying line-cnt from 1 by 1 until line-cnt > 8
           move gpcmd(line-cnt) to gnuplot-command
           write gnuplot-command end-write
       end-perform
       close scriptfile

      *><* Create the reciprocal data
       open output outfile
       move spaces to outrec
       compute xstep = function e / 100 end-compute
       perform
           with test after
           varying x from 1 by xstep
           until x >= function e
               if x > function e
                   move function e to x-value
               else
                   move x to x-value
               end-if
               compute recip = 1 / x end-compute
               move recip to y-value
               write outrec end-write
       end-perform
       close outfile

      *><* Invoke gnuplot
       call "SYSTEM" using gplot returning result end-call
       if result not = 0
           display "Problem: " result end-display
           stop run returning result
       end-if

       goback.
       end program ploteuler.

The area in red is exactly 1. Well, not on this plot exactly, as it is somewhat sloppy with the xstep end case and the precisions.

_images/euler.png

See Can OpenCOBOL be used for plotting? for some details on plotting.

4.2.17   FUNCTION EXCEPTION-FILE

This special-register holds the error number and name of the source file that caused an input output exception. See FUNCTION EXCEPTION-STATUS for an example.

4.2.18   FUNCTION EXCEPTION-LOCATION

This special-register can be queried for the location of the last exception. See FUNCTION EXCEPTION-STATUS for example source code. Note: This feature requires compilation with -fsource-location compiler switch. This option is also turned on with -g and -debug debugging info compiles. Information includes PROGRAM-ID, section and source line.

4.2.19   FUNCTION EXCEPTION-STATEMENT

This special-register holds the statement that was executing when the latest exception was raised. See FUNCTION EXCEPTION-STATUS for an example. Note: This feature requires compilation with -fsource-location compiler switch. This option is also turned on with -g debugging info compiles.

4.2.20   FUNCTION EXCEPTION-STATUS

This FUNCTION returns the current exception status. The example below is courtesy of Roger While, from a post he made announcing the FUNCTION EXCEPTION- features.

Source format is free, compile with cobc -x -g -free except.cob

IDENTIFICATION DIVISION.
PROGRAM-ID. MINIPROG.

ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. LINUX.
OBJECT-COMPUTER. LINUX.
SPECIAL-NAMES.

INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT PRINTFILE ASSIGN TO "XXRXWXX"
FILE STATUS RXWSTAT.

DATA DIVISION.
FILE SECTION.
FD PRINTFILE.
01 PRINTREC PIC X(132).

WORKING-STORAGE SECTION.
01 RXWSTAT PIC XX.

PROCEDURE DIVISION.
A00-MAIN SECTION.
001-MAIN-PROCEDURE.
OPEN INPUT PRINTFILE.
DISPLAY "File Status: " RXWSTAT.
DISPLAY "EXCEPTION-FILE: " FUNCTION EXCEPTION-FILE.
DISPLAY "Return Length: "
    FUNCTION LENGTH (FUNCTION EXCEPTION-FILE).
DISPLAY "EXCEPTION-STATUS: " FUNCTION EXCEPTION-STATUS.
DISPLAY "EXCEPTION-STATEMENT: " FUNCTION EXCEPTION-STATEMENT.
STRING "TOOLONG" DELIMITED SIZE INTO RXWSTAT.
DISPLAY "EXCEPTION-STATUS: " FUNCTION EXCEPTION-STATUS.
DISPLAY "EXCEPTION-STATEMENT: " FUNCTION EXCEPTION-STATEMENT.
DISPLAY "EXCEPTION-LOCATION: " FUNCTION EXCEPTION-LOCATION.

STOP RUN.

Example output:

File Status: 35
EXCEPTION-FILE: 35PRINTFILE
Return Length: 00000011
EXCEPTION-STATUS: EC-I-O-PERMANENT-ERROR
EXCEPTION-STATEMENT: OPEN
EXCEPTION-STATUS: EC-OVERFLOW-STRING
EXCEPTION-STATEMENT: STRING
EXCEPTION-LOCATION: MINIPROG; 001-MAIN-PROCEDURE OF A00-MAIN; 29

Tip

See the source file libcob/exception.def for a list of the plethora of run-time exceptions supported by OpenCOBOL.

4.2.21   FUNCTION EXP

Returns an approximation of Euler’s number (see FUNCTION E) raised to the power of the numeric argument.

DISPLAY FUNCTION EXP(1) END-DISPLAY

outputs:

2.718281828459045091

Note

Be aware that this approximation seems accurate to “only” 15 decimal places. Diligent programmers need to be aware of the foibles of floating point mathematics and take these issues into consideration.

4.2.22   FUNCTION EXP10

Returns an approximation of the value 10 raised to the power of the numeric argument.

DISPLAY FUNCTION EXP10(1.0) END-DISPLAY
DISPLAY FUNCTION EXP10(1.2) END-DISPLAY
DISPLAY FUNCTION EXP10(10) END-DISPLAY

Outputs:

10.000000000000000000
15.848931924611132871
10000000000.000000000000000000

4.2.23   FUNCTION FACTORIAL

Computes the factorial of the integral argument. Valid Range of 0 to 19 with a domain of 1 to 121645100408832000.

OCOBOL*> ***************************************************************
      *> Program to find range and domain of FUNCTION FACTORIAL
       identification division.
       program-id. fact.

       data division.
       working-storage section.
       01 ind pic 999.
       01 result pic 9(18).

      *> ***************************************************************
       procedure division.
       perform varying ind from 0 by 1 until ind > 20
           add zero to function factorial(ind) giving result
               on size error
                   display "overflow at " ind end-display
           end-add
           display ind " = " function factorial(ind) end-display
       end-perform

       goback.
       end program fact.

Outputs:

000 = 000000000000000001
001 = 000000000000000001
002 = 000000000000000002
003 = 000000000000000006
004 = 000000000000000024
005 = 000000000000000120
006 = 000000000000000720
007 = 000000000000005040
008 = 000000000000040320
009 = 000000000000362880
010 = 000000000003628800
011 = 000000000039916800
012 = 000000000479001600
013 = 000000006227020800
014 = 000000087178291200
015 = 000001307674368000
016 = 000020922789888000
017 = 000355687428096000
018 = 006402373705728000
019 = 121645100408832000
overflow at 020
020 = 432902008176640000

Kind of the same thing, with some zero out formatting.

OCOBOL*> ***************************************************************
      *> Program to find range and domain of FUNCTION FACTORIAL
       identification division.
       program-id. fact.

       data division.
       working-storage section.
       01 ind                  pic 99.
       01 z-ind                pic z9.
       01 result               pic 9(18).
       01 pretty-result        pic z(17)9.

      *> ***************************************************************
       procedure division.
       perform varying ind from 0 by 1 until ind > 21
           add zero to function factorial(ind) giving result
               on size error
                   display
                       "overflow at " ind ", result undefined: "
                       function factorial(ind)
                   end-display
               not on size error
                   move ind to z-ind
                   move result to pretty-result
                   display
                       "factorial(" z-ind ") = " pretty-result
                   end-display
           end-add
       end-perform

       goback.
       end program fact.

Which outputs:

factorial( 0) =                  1
factorial( 1) =                  1
factorial( 2) =                  2
factorial( 3) =                  6
factorial( 4) =                 24
factorial( 5) =                120
factorial( 6) =                720
factorial( 7) =               5040
factorial( 8) =              40320
factorial( 9) =             362880
factorial(10) =            3628800
factorial(11) =           39916800
factorial(12) =          479001600
factorial(13) =         6227020800
factorial(14) =        87178291200
factorial(15) =      1307674368000
factorial(16) =     20922789888000
factorial(17) =    355687428096000
factorial(18) =   6402373705728000
factorial(19) = 121645100408832000
overflow at 20, result undefined, 432902008176640000
overflow at 21, result undefined, 197454024290336768

4.2.24   FUNCTION FRACTION-PART

Returns a numeric value that is the fraction part of the argument. Keeping the sign.

DISPLAY FUNCTION FRACTION-PART(FUNCTION E) END-DISPLAY
DISPLAY FUNCTION FRACTION-PART(-1.5) END-DISPLAY
DISPLAY FUNCTION FRACTION-PART(-1.0) END-DISPLAY
DISPLAY FUNCTION FRACTION-PART(1) END-DISPLAY

Outputs:

+.718281828459045235
-.500000000000000000
+.000000000000000000
+.000000000000000000

4.2.25   FUNCTION INTEGER

Returns the greatest integer less than or equal to the numeric argument.

DISPLAY
    FUNCTION INTEGER (-3)      SPACE
    FUNCTION INTEGER (-3.141)
END-DISPLAY
DISPLAY
    FUNCTION INTEGER (3)       SPACE
    FUNCTION INTEGER (3.141)
END-DISPLAY
DISPLAY
    FUNCTION INTEGER (-0.3141) SPACE
    FUNCTION INTEGER (0.3141)  SPACE
    FUNCTION INTEGER (0)
END-DISPLAY

Outputs:

-000000000000000003 -000000000000000004
+000000000000000003 +000000000000000003
-000000000000000001 +000000000000000000 +000000000000000000

Note the -4, greatest integer less than or equal to the argument.

4.2.26   FUNCTION INTEGER-OF-DATE

Converts a date in the Gregorian calender to an integer form. Expects a numeric argument in the form YYYYMMDD based on years greater than or equal to 1601 and less than 10000. Month values range from 1 to 12. Days range from 1 to 31 and should be valud for the specified month and year. Invalid input returns unpredictable results and sets the exception EC-ARGUMENT-FUNCTION to exist. See FUNCTION DATE-OF-INTEGER for the converse function.

4.2.27   FUNCTION INTEGER-OF-DAY

Converts a Julian date of YYYYDDD to integer date form. See FUNCTION DAY-OF-INTEGER for the converse intrinsic function. Invalid arguments return an undefined result and set the exception EC-ARGUMENT-FUNCTION to exist.

4.2.28   FUNCTION INTEGER-PART

Returns the integer part of the numeric argument. Similar to FUNCTION INTEGER but returns different values for negative arguments.

DISPLAY
    FUNCTION INTEGER-PART (-3)      SPACE
    FUNCTION INTEGER-PART (-3.141)
END-DISPLAY
DISPLAY
    FUNCTION INTEGER-PART (3)       SPACE
    FUNCTION INTEGER-PART (3.141)
END-DISPLAY
DISPLAY
    FUNCTION INTEGER-PART (-0.3141) SPACE
    FUNCTION INTEGER-PART (0.3141)  SPACE
    FUNCTION INTEGER-PART (0)
END-DISPLAY

Outputs:

-000000000000000003 -000000000000000003
+000000000000000003 +000000000000000003
+000000000000000000 +000000000000000000 +000000000000000000

4.2.29   FUNCTION LENGTH

Returns an integer that is the length in character positions of the given argument.

working storage.
01 nat     pic n(10).
01 cha     pic x(10).
01 bin     constant as h'ff'.

01 num     pic s9(8)v9(8).
01 form    pic $-z(7)9.9(8).

procedure division.
display
    function length(nat) space
    function length(cha) space
    function length(bin)
end-display
display
    function length(num) space
    function length(form)
end-display

Outputs:

20 10 3
16 19

4.2.30   FUNCTION LOCALE-DATE

Returns a culturally appropriate date given an alphanumeric of 8 character positions in the form “YYYYMMDD” and an optional locale name that has been associted with a locale in the SPECIAL-NAMES paragraph.

See http://en.wikipedia.org/wiki/Locale for a start at the very detail rich computational requirements of LOCALE.

Will set EC-ARGUMENT-FUNCTION to exist for invalid input.

OCOBOL >>SOURCE FORMAT IS FIXED
      *> ***************************************************************
      *> Author:    Brian Tiffin
      *> Date:      20120116
      *> Purpose:   Demonstrate locale functions
      *> Tectonics: cobc -x locales.cob
      *> ***************************************************************
       identification division.
       program-id. locales.

       environment division.
       configuration section.
       repository.
           function all intrinsic.

      *> -*********-*********-*********-*********-*********-*********-**
       procedure division.

      *> Display cultural norm date and times as set in environment.
      *>   Google LC_ALL.
      *> 20120622 represents June 22 2012
      *> 141516 represents 2pm (14th hour), 15 minutes, 16 seconds
      *> 39600 represents 11 hours in seconds

       display locale-date(20120622)            end-display
       display locale-time(141516)              end-display
       display locale-time-from-seconds(39600)  end-display

       goback.
       end program locales.

Which produced:

[btiffin@home cobol]$ cobc -x locales.cob
[btiffin@home cobol]$ ./locales
06/22/2012
02:15:16 PM
11:00:00 AM

I live in Canada, but usually run Fedora with LANG=en_US.utf8

and so

[btiffin@home cobol]$ export LANG='en_CA.utf8'
[btiffin@home cobol]$ ./locales
22/06/12
02:15:16 PM
11:00:00 AM

Boo, day month year form. Sad, 2 digit year? What kinda backwater land do I live in? Time to write strongly worded letters to some committees. :)

I just looked, and it seems Canada is listed as DD/MM/YY; I’m moving to Germany.

[btiffin@home cobol]$ export LANG=en_DK.utf8
[btiffin@home cobol]$ ./locales
2012-06-22
14:15:16
11:00:00

Joy. year month day. Hmm, what about Hong Kong?

[btiffin@home cobol]$ LANG=en_HK.utf8 ./locales
Sunday, June 22, 2012
02:15:16 EST
11:00:00 EST

Nice.

If you want to run your system through its locales, try

$ locs=( $(locale -a) )
$ for l in ${locs[@]}; do echo $l; LANG=$l ./locales; done

and expect some unicode in the output.

Oh, and along with FUNCTION EXCEPTION-STATUS you can detect invalid arguments.

000100 >>SOURCE FORMAT IS FIXED
000200*> ***************************************************************
000300*> Author:    Brian Tiffin
000400*> Date:      20120116
000500*> Purpose:   Demonstrate locale function invalid arguments
000600*> Tectonics: cobc -x -g -debug locales.cob
000700*> ***************************************************************
000800 identification division.
000900 program-id. locales.
001000
001100 environment division.
001200 configuration section.
001300 repository.
001400     function all intrinsic.
001500
001600*> -*********-*********-*********-*********-*********-*********-**
001700 procedure division.
001800
001900*> Display cultural norm date and times as set in environment.
002000*>   Google LC_ALL.
002100*> 20120622 represents June 22 2012
002200*> 141516 represents 2pm (14th hour), 15 minutes, 16 seconds
002300*> 39600 represents 11 hours in seconds
002400
002500 display locale-date(20120622)            end-display
002600 display locale-time(141516)              end-display
002700 display locale-time-from-seconds(39600)  end-display
002800
002900*> invalid arguments are detected through EXCEPTION-STATUS
003000 display locale-date(20120699)            end-display
003100 DISPLAY "EXCEPTION-STATUS: " EXCEPTION-STATUS
003200 DISPLAY "EXCEPTION-STATEMENT: " EXCEPTION-STATEMENT
003300 DISPLAY "EXCEPTION-LOCATION: " EXCEPTION-LOCATION
003400
003500 display locale-time(941516)              end-display
003600 DISPLAY "EXCEPTION-STATUS: " EXCEPTION-STATUS
003700 DISPLAY "EXCEPTION-STATEMENT: " EXCEPTION-STATEMENT
003800 DISPLAY "EXCEPTION-LOCATION: " EXCEPTION-LOCATION
003900
004000 display locale-time-from-seconds(-39600) end-display
004100
004200 goback.
004300 end program locales.

giving:

$ ./locales
06/22/2012
02:15:16 PM
11:00:00 AM

EXCEPTION-STATUS: EC-ARGUMENT-FUNCTION
EXCEPTION-STATEMENT: DISPLAY
EXCEPTION-LOCATION: locales; MAIN PARAGRAPH OF MAIN SECTION; 30

EXCEPTION-STATUS: EC-ARGUMENT-FUNCTION
EXCEPTION-STATEMENT: DISPLAY
EXCEPTION-LOCATION: locales; MAIN PARAGRAPH OF MAIN SECTION; 35
-11:00:00 AM

4.2.31   FUNCTION LOCALE-TIME

Returns a culturally appropriate date given an alphanumeric of 6 character positions in the form “HHMMSS” and an optional locale name that has been associted with a locale in the SPECIAL-NAMES paragraph. See http://en.wikipedia.org/wiki/Locale for a start at the very detail rich computational requirements of LOCALE.

Will set EC-ARGUMENT-FUNCTION to exist for invalid input.

See FUNCTION LOCALE-DATE.

4.2.32   FUNCTION LOCALE-TIME-FROM-SECONDS

Returns a culturally appropriate date given an alphanumeric number of seconds and an optional locale name that has been associted with a locale in the SPECIAL-NAMES paragraph.

See http://en.wikipedia.org/wiki/Locale for a start at the very detail rich computational requirements of LOCALE.

Will set EC-ARGUMENT-FUNCTION to exist for invalid input.

See FUNCTION LOCALE-DATE.

4.2.33   FUNCTION LOG

Returns an approximation of the natural logarithmic value of the given numeric argument. Uses a base of FUNCTION E.

DISPLAY FUNCTION LOG(100) END-DISPLAY
DISPLAY FUNCTION LOG(FUNCTION E) END-DISPLAY

gives:

4.60517018598809137
000000001

4.2.34   FUNCTION LOG10

Returns an approximation of the base-10 logarithmic value of the given numeric argument.

DISPLAY FUNCTION LOG10(100) END-DISPLAY

gives:

000000002

4.2.35   FUNCTION LOWER-CASE

Convert any uppercase character values (A-Z) in the argument to lowercase (a-z).

4.2.36   FUNCTION MAX

Returns the maximum value from the list of arguments.

DISPLAY FUNCTION MAX ( "def"; "abc";) END-DISPLAY
DISPLAY FUNCTION MAX ( 123.1; 123.11; 123) END-DISPLAY

Outputs:

def
123.11

4.2.37   FUNCTION MEAN

Returns the arithmetic mean (average) of the list of numeric arguments.

DISPLAY FUNCTION MEAN(1; 2; 3; 4; 5; 6; 7; 8; 9) END-DISPLAY

Outputs:

+5.00000000000000000

4.2.38   FUNCTION MEDIAN

Returns the middle value of the arguments formed by arranging the list in sorted order.

DISPLAY FUNCTION MEDIAN(1; 2; 3; 4; 5; 6; 7; 8; 9) END-DISPLAY

Outputs:

5

4.2.39   FUNCTION MIDRANGE

Returns the arithmetic mean (average) of the minimum and maximum argument from the list of numeric arguments.

DISPLAY FUNCTION MIDRANGE(1; 2; 3; 4; 5; 6; 7; 8; 9) END-DISPLAY

Outputs:

5.000000000000000000

4.2.40   FUNCTION MIN

Returns the minimum value from the list of arguments.

DISPLAY FUNCTION MIN ( "def"; "abc";) END-DISPLAY
DISPLAY FUNCTION MIN ( 123.1; 123.11; 123) END-DISPLAY

Outputs:

abc
123

4.2.41   FUNCTION MOD

Returns an integer value of that is the first-argument modulo second-argument.

DISPLAY FUNCTION MOD(123; 23) END-DISPLAY

Outputs:

+000000000000000008

4.2.42   FUNCTION NUMVAL

Returns the numeric value represented by the character string argument.

OCOBOL IDENTIFICATION   DIVISION.
       PROGRAM-ID.      prog.
       DATA             DIVISION.
       WORKING-STORAGE  SECTION.
       01  X   PIC   X(12) VALUE " -9876.1234 ".
       01  F   PIC   X(12) VALUE "B-9876.1234 ".
       PROCEDURE        DIVISION.
           DISPLAY FUNCTION NUMVAL ( X )
           DISPLAY FUNCTION NUMVAL ( F )
           END-DISPLAY.
           STOP RUN.

gives:

-09876.1234
000000000

The “B” in field F, breaks the numeric conversion. NUMVAL is actually fairly complicated and forgiving of inputs, but will return 0 on invalid numeric conversions.

OpenCOBOL 2 will also provide FUNCTION TEST-NUMVAL.

4.2.43   FUNCTION NUMVAL-C

Returns the numeric value represented by the culturally appropriate currency specification argument.

OCOBOL IDENTIFICATION   DIVISION.
       PROGRAM-ID.      prog.
       DATA             DIVISION.
       WORKING-STORAGE  SECTION.
       01  X   PIC   X(14) VALUE " % -9876.1234 ".
       PROCEDURE        DIVISION.
           DISPLAY FUNCTION NUMVAL-C ( X , "%" )
           END-DISPLAY.
           STOP RUN.

gives:

-09876.1234

in a LOCALE that uses the percent sign as a currency symbol.

OpenCOBOL 2 will also provide FUNCTION TEST-NUMVAL-C.

4.2.44   FUNCTION ORD

Returns the integer value that is the ordinal position of the character argument in the program’s collating sequence. COBOL uses 1 as the lowest ordinal for character sequencing.

DISPLAY FUNCTION ORD("J") END-DISPLAY

Outputs (on an ASCII system with no ALPHABET clause):

00000075

Note that COBOL uses 1 as the first value for collating. So ASCII 74 is ORD 75 for “J”.

4.2.45   FUNCTION ORD-MAX

Returns the integer that is the ordinal position of the maximum value of the given argument list.

DISPLAY ORD-MAX(9; 8; 7; 6; 5; 4; 3; 2; 1) END-DISPLAY
DISPLAY ORD-MAX('abc'; 'def'; 'ghi') END-DISPLAY

Outputs:

00000001
00000003

4.2.46   FUNCTION ORD-MIN

Returns the integer that is the ordinal position of the minimum value from the argument list.

OCOBOL >>SOURCE FORMAT IS FIXED
      *> ***************************************************************
      *> Author:    Brian Tiffin
      *> Date:      20090531
      *> Purpose:   Demonstration of FUNCTION ORD-MIN and REPOSITORY
      *> Tectonics: cobc -x ordmin.cob
      *> ***************************************************************
       identification division.
       program-id. ordmin.

       environment division.
       configuration section.
       repository.
           function all intrinsic.

       data division.
       working-storage section.
       01 posmin               pic 9(8).

      *> ***************************************************************
       procedure division.
       move ord-min (9; 8; 7; 6; 5; 4; 3; 2; 1; 2; 3; 4; 5) to posmin
       display posmin end-display
       move ord-min ("abc"; "def"; "000"; "def"; "abc") to posmin
       display posmin end-display
       goback.
       end program ordmin.

Outputs:

00000009
00000003

Notice how ord-min did not require FUNCTION, as the REPOSITORY entry allows this to be skipped in the source codes.

4.2.47   FUNCTION PI

Returns an approximation of the ratio of the circumference by the diameter of a circle. It returns an alphanumeric with 34 digits after the decimal. Please be aware of the limitations of using these types of approximated values in computations.

OCOBOL >>SOURCE FORMAT IS FIXED
      *> ***************************************************************
      *> Author:    Brian Tiffin
      *> Date:      20101030
      *> Purpose:   Demonstrate PI
      *> Tectonics: cobc -x pi-demo.cob
      *> ***************************************************************
       identification division.
       program-id. pi-demo.

       data division.
       working-storage section.
       01 args pic x(80).
       01 diameter pic 999 value 1.
       01 show-diameter pic zz9.
       01 circumference usage float-long.
       01 plural pic xx.
       01 plural-length pic 9 value 1.
       01 newline pic x value x'0a'.

      *> ***************************************************************
       procedure division.
       accept args from command-line end-accept
       if args not equal spaces
           move args to diameter
       end-if

       if diameter not equal 1
           move "s " to plural
           move 2 to plural-length
       else
           move "  " to plural
           move 1 to plural-length
       end-if
       move diameter to show-diameter

       display "FUNCTION PI is " function pi newline end-display

       compute circumference = function pi * diameter end-compute
       display
           "A wheel, " show-diameter " metre" plural(1:plural-length)
           "wide will roll, very close to but only approximately, "
           newline circumference " metres in ONE full rotation."
           newline
       end-display

       goback.
       end program pi-demo.

Outputs:

$ cobc -x pi-demo.cob && ./pi-demo && ./pi-demo 42
FUNCTION PI is 3.1415926535897932384626433832795029

A wheel,   1 metre wide will roll, very close to but only approximately,
3.14159265358979312 metres in ONE full rotation.

FUNCTION PI is 3.1415926535897932384626433832795029

A wheel,  42 metres wide will roll, very close to but only approximately,
131.946891450771318 metres in ONE full rotation.

4.2.48   FUNCTION PRESENT-VALUE

Returns an approximation of the present value from a discount rate and list of future period end amounts. It attempts to reflect the future value of $1.00 given time, inflation and interest.

OCOBOL >>SOURCE FORMAT IS FIXED
      *> ***************************************************************
      *> Author:    Brian Tiffin
      *> Date:      20101030
      *> Purpose:   Demo of PRESENT-VALUE
      *> Tectonics: cobc -x present-value-demo.cob
      *> ***************************************************************
       identification division.
       program-id. present-value-demo.

       data division.
       working-storage section.
       01 args pic x(80).
       01 newline pic x value x'0a'.
       01 rate pic s9v9999 value 0.7000.
       01 the-value pic s9(6)v99.

      *> ***************************************************************
       procedure division.
       accept args from command-line end-accept

       if args not equal to spaces
           move args to rate
       end-if

       compute the-value rounded =
           function present-value(rate; 1000, 1010, 1000, 1100)
       end-compute
       display
            "A discount rate of " rate " gives a PRESENT-VALUE of "
            the-value " given" newline
            "end-amounts of 1000, 1010, 1000 and 1100"
       end-display

       compute the-value rounded =
           function present-value(rate; 1000, 1000, 1000, 1000)
       end-compute
       display
            "A discount rate of " rate " gives a PRESENT-VALUE of "
            the-value " given" newline
            "end-amounts of 1000, 1000, 1000 and 1000"
       end-display

       goback.
       end program present-value-demo.

Outputs:

$ ./present-value-demo
A discount rate of +0.7000 gives a PRESENT-VALUE of +001272.96 given
end-amounts of 1000, 1010, 1000 and 1100
A discount rate of +0.7000 gives a PRESENT-VALUE of +001257.53 given
end-amounts of 1000, 1000, 1000 and 1000
$ ./present-value-demo 0.333
A discount rate of +0.3330 gives a PRESENT-VALUE of +002089.18 given
end-amounts of 1000, 1010, 1000 and 1100
A discount rate of +0.3330 gives a PRESENT-VALUE of +002051.88 given
end-amounts of 1000, 1000, 1000 and 1000
$ ./present-value-demo 0.935
A discount rate of +0.9350 gives a PRESENT-VALUE of +001003.03 given
end-amounts of 1000, 1010, 1000 and 1100
A discount rate of +0.9350 gives a PRESENT-VALUE of +000993.23 given
end-amounts of 1000, 1000, 1000 and 1000

For details, talk to a professional.

rant Any COBOL programmer using financial functions for use by others HAS to attain some level of domain expertise in the mathematics at work, as well as a level of technical competence to read through and defend both the COBOL source code and the generated C code that OpenCOBOL emits before compiling. rant over

4.2.49   FUNCTION RANDOM

Returns a pseudo-random number given a numeric seed value as argument.

DISPLAY FUNCTION RANDOM(1) END-DISPLAY
DISPLAY FUNCTION RANDOM(1) END-DISPLAY
DISPLAY FUNCTION RANDOM() END-DISPLAY

Outputs:

+00000000.1804289383
+00000000.1804289383
+000000000.846930886

4.2.50   FUNCTION RANGE

Returns the value of the minimum argument subtracted from the maximum argument from the list of numeric arguments.

DISPLAY FUNCTION RANGE(1; 2; 3; 4; 5; 6; 7; 8; 9) END-DISPLAY

Outputs:

+000000000000000008

4.2.51   FUNCTION REM

Returns the numeric remainder of the first argument divided by the second.

DISPLAY FUNCTION REM(123; 23) END-DISPLAY

Outputs:

+000000000000000008

4.2.52   FUNCTION REVERSE

Returns the reverse of the given character string.

DISPLAY FUNCTION REVERSE("abc") END-DISPLAY

Outputs:

cba

4.2.53   FUNCTION SECONDS-FROM-FORMATTED-TIME

This function converts a time that is in a specified format to a numeric value representing the number of seconds after midnight.

OCOBOL IDENTIFICATION   DIVISION.
       PROGRAM-ID.      prog.
       DATA             DIVISION.
       WORKING-STORAGE  SECTION.
       01  X   PIC      X(6)   VALUE "hhmmss".
       01  Y   PIC      9(8)   COMP-5.
       01  Z   PIC      X(6)   VALUE "010203".
       PROCEDURE        DIVISION.
           MOVE FUNCTION SECONDS-FROM-FORMATTED-TIME (X, Z) TO Y.
           IF Y NOT = 3723
                   DISPLAY Y
                   END-DISPLAY
           END-IF.
           STOP RUN.

This test would fail if 01:02:03 was not returned as 3723 seconds past midnight.

Argumenent 1 takes the form hhmmss and expectes argument 2 to be a matching length numeric item, or 0 is returned.

4.2.54   FUNCTION SECONDS-PAST-MIDNIGHT

Returns the seconds past midnight from the current system time.

4.2.55   FUNCTION SIGN

Returns +1 for positive, 0 for zero and -1 for a negative numeric argument.

4.2.56   FUNCTION SIN

Returns an approximation for the trigonometric sine of the given numeric angle (expressed in radians) argument. See Can OpenCOBOL be used for plotting? for a sample graph using gnuplot.

4.2.57   FUNCTION SQRT

Returns an approximation of the square root of the given numeric argument.

DISPLAY FUNCTION SQRT(-1) END-DISPLAY
CALL "perror" USING NULL END-CALL
DISPLAY FUNCTION SQRT(2) END-DISPLAY

Outputs:

0.000000000000000000
Numerical argument out of domain
1.414213562373095145

Note: CALL “perror” reveals a bug in OpenCOBOL versions packaged before June 2009 where the stack will evetually underflow due to improper handling of the void return specification. Versions supporting RETURNING NULL fix this problem. An actual application that needed to verify the results of square roots or other numerical function would be better off placing a small C wrapper to set and get the global errno.

4.2.58   FUNCTION STANDARD-DEVIATION

Returns an approximation of the standard deviation from the given list of numeric arguments.

DISPLAY
    FUNCTION STANDARD-DEVIATION(1 2 3 4 5 6 7 8 9 10) SPACE
    FUNCTION STANDARD-DEVIATION(1 2 3 4 5 6 7 8 9 100)
END-DISPLAY
2.872281323269014308 28.605069480775604518

4.2.59   FUNCTION STORED-CHAR-LENGTH

Returns the numeric value of the internal storage length of the given argument in bytes, not counting spaces.

4.2.60   FUNCTION SUBSTITUTE

FUNCTION SUBSTITUTE is an OpenCOBOL extension to the suite of intrinsic functions.

DISPLAY
    FUNCTION SUBSTITUTE("this is a test",
        "this", "that",
        "is a", "was",
        "test", "very cool!")
END-DISPLAY

Will display:

that was very cool!

having changed this for that, is a for was and test with very cool!

The new intrinsic accepts:

SUBSTITUTE(subject, lit-pat-1, repl-1 [, litl-pat-2, repl-2, ...])

where lit-pat just means the scan is for literals, not that you have to use literal constants. WORKING-STORAGE identifiers are fine for any of the subject, the search patterns or the replacements.

As with all intrinsics, you receive a new field and the subject is untouched.

Note

The resulting field can be shorter, the same length or longer than the subject string.

This is literal character global find and replace, and there are no wildcards or other pattern expressions. Unlike INSPECT, this function does not require same length patterns and replacements. Each pattern replacement pair uses the original subject, not any intermediate in progress result.

As this is an alphanumeric operation, a reference modification is also allowed

MOVE FUNCTION SUBSTITUTE(subject, pat, repl)(2:4) TO xvar4

to result in 4 characters starting at the second position after the substitution.

4.2.61   FUNCTION SUBSTITUTE-CASE

Similar to SUBSTITUTE, but ignores upper and lower case of subject when matching patterns.

4.2.62   FUNCTION SUM

Returns the numeric value that is the sum of the given list of numeric arguments.

4.2.63   FUNCTION TAN

Returns an approximation for the trigonometric tangent of the given numeric angle (expressed in radians) argument. Returns ZERO if the argument would cause an infinity or other size error.

4.2.64   FUNCTION TEST-DATE-YYYYMMDD

Test for valid date in numeric yyyymmdd form.

4.2.65   FUNCTION TEST-DAY-YYYYDDD

Test for valid date in numeric yyyyddd form.

4.2.66   FUNCTION TRIM

Returns a character string that is the argument trimmed of spaces. Defaults to trimming both ends, but can be passed LEADING or TRAILING qualifier arguments.

DISPLAY '"' FUNCTION TRIM("   abc   ") '"' END-DISPLAY
DISPLAY '"' FUNCTION TRIM("   abc   " LEADING) '"' END-DISPLAY
DISPLAY '"' FUNCTION TRIM("   abc   " TRAILING) '"' END-DISPLAY

Outputs:

"abc"
"abc   "
"   abc"

4.2.67   FUNCTION UPPER-CASE

Returns a copy of the alphanumeric argument with any lower case letters replaced by upper case letters.

DISPLAY FUNCTION UPPER-CASE("# 123 abc DEF #") END-DISPLAY

Outputs:

# 123 ABC DEF #

4.2.68   FUNCTION VARIANCE

Returns the variance of a series of numbers. The variance is defined as the square of the FUNCTION STANDARD-DEVIATION

DISPLAY FUNCTION VARIANCE(1 2 3 4 5 6 7 8 9 100) END-DISPLAY.
+818.250000000000000

4.2.69   FUNCTION WHEN-COMPILED

Returns a 21 character alphanumeric field of the form YYYYMMDDhhmmsscc±zzzz e.g. 2008070505152000-0400 representing when a module or executable is compiled. The WHEN-COMPILED special register reflects when an object module was compiled

program-id. whenpart1. procedure division.
display "First part :" FUNCTION WHEN-COMPILED end-display.

program-id. whenpart2. procedure division.
display "Second part:" FUNCTION WHEN-COMPILED end-display.

program-id. whenshow. procedure division.
call "whenpart1" end-call.
call "whenpart2" end-call.
display "Main part  :" FUNCTION WHEN-COMPILED end-display.

For a test

$ cobc -c whenpart1.cob && sleep 15 && cobc -c whenpart2.cob &&
> sleep 15 && cobc -x whenshow.cob whenpart1.o whenpart2.o
$ ./whenshow

gives:

First part :2008082721391500-0400
Second part:2008082721393000-0400
Main part  :2008082721394500-0400

4.2.70   FUNCTION YEAR-TO-YYYY

Converts a two digit year to a sliding window four digit year. The optional second argument (default 50) is added to the date at execution time to determine the ending year of a 100 year interval.

4.3   Can you clarify the use of FUNCTION in OpenCOBOL?

Yes. This information is from [Roger], posted to the opencobol forums.

Just to clarify the use of FUNCTION.
(Applies to 0.33)
FUNCTION (generally speaking, there are exceptions) can
be used anywhere where a source item is valid.
It always results in a new temporary field.
This will have the desired characteristics dependant
on the parameters.
eg. FUNCTION MIN (x, y, z)
with x PIC 99
     y PIC 9(8) COMP
     z PIC 9(6)V99
will result in returning a field that has
at least 8 positions before the (implied) decimal
point and 2 after.

It does NOT ever change the contents of parameters
to the function.

FUNCTION's are nestable.
eg.

DISPLAY FUNCTION REVERSE (FUNCTION UPPER-CASE (myfield)).

One clarification to the above quote was pointed out by Roger. The line:

be used anywhere where a source item is valid.

should be:

be used anywhere where a sending field is valid.

4.4   What is the difference between the LENGTH verb and FUNCTION LENGTH?

From [Roger]:

The standard only defines FUNCTION LENGTH.
The LENGTH OF phrase is an extension (from MF)

4.5   What STOCK CALL LIBRARY does OpenCOBOL offer?

OpenCOBOL 1.0 ships with quite a few callable features. See CALL. Looking through the source code, you’ll find the current list of service calls in:

libcob/system.def

With the 1.1 pre-release of July 2008, that list included

/* COB_SYSTEM_GEN (external name, number of parameters, internal name) */

COB_SYSTEM_GEN ("SYSTEM", 1, SYSTEM)
COB_SYSTEM_GEN ("CBL_ERROR_PROC", 2, CBL_ERROR_PROC)
COB_SYSTEM_GEN ("CBL_EXIT_PROC", 2, CBL_EXIT_PROC)
COB_SYSTEM_GEN ("CBL_OPEN_FILE", 5, CBL_OPEN_FILE)
COB_SYSTEM_GEN ("CBL_CREATE_FILE", 5, CBL_CREATE_FILE)
COB_SYSTEM_GEN ("CBL_READ_FILE", 5, CBL_READ_FILE)
COB_SYSTEM_GEN ("CBL_WRITE_FILE", 5, CBL_WRITE_FILE)
COB_SYSTEM_GEN ("CBL_CLOSE_FILE", 1, CBL_CLOSE_FILE)
COB_SYSTEM_GEN ("CBL_FLUSH_FILE", 1, CBL_FLUSH_FILE)
COB_SYSTEM_GEN ("CBL_DELETE_FILE", 1, CBL_DELETE_FILE)
COB_SYSTEM_GEN ("CBL_COPY_FILE", 2, CBL_COPY_FILE)
COB_SYSTEM_GEN ("CBL_CHECK_FILE_EXIST", 2, CBL_CHECK_FILE_EXIST)
COB_SYSTEM_GEN ("CBL_RENAME_FILE", 2, CBL_RENAME_FILE)
COB_SYSTEM_GEN ("CBL_GET_CURRENT_DIR", 3, CBL_GET_CURRENT_DIR)
COB_SYSTEM_GEN ("CBL_CHANGE_DIR", 1, CBL_CHANGE_DIR)
COB_SYSTEM_GEN ("CBL_CREATE_DIR", 1, CBL_CREATE_DIR)
COB_SYSTEM_GEN ("CBL_DELETE_DIR", 1, CBL_DELETE_DIR)
COB_SYSTEM_GEN ("CBL_AND", 3, CBL_AND)
COB_SYSTEM_GEN ("CBL_OR", 3, CBL_OR)
COB_SYSTEM_GEN ("CBL_NOR", 3, CBL_NOR)
COB_SYSTEM_GEN ("CBL_XOR", 3, CBL_XOR)
COB_SYSTEM_GEN ("CBL_IMP", 3, CBL_IMP)
COB_SYSTEM_GEN ("CBL_NIMP", 3, CBL_NIMP)
COB_SYSTEM_GEN ("CBL_EQ", 3, CBL_EQ)
COB_SYSTEM_GEN ("CBL_NOT", 2, CBL_NOT)
COB_SYSTEM_GEN ("CBL_TOUPPER", 2, CBL_TOUPPER)
COB_SYSTEM_GEN ("CBL_TOLOWER", 2, CBL_TOLOWER)
COB_SYSTEM_GEN ("\364", 2, CBL_XF4)
COB_SYSTEM_GEN ("\365", 2, CBL_XF5)
COB_SYSTEM_GEN ("\221", 2, CBL_X91)
COB_SYSTEM_GEN ("C$NARG", 1, cob_return_args)
COB_SYSTEM_GEN ("C$PARAMSIZE", 1, cob_parameter_size)
COB_SYSTEM_GEN ("C$MAKEDIR", 1, cob_acuw_mkdir)
COB_SYSTEM_GEN ("C$CHDIR", 2, cob_acuw_chdir)
COB_SYSTEM_GEN ("C$SLEEP", 1, cob_acuw_sleep)
COB_SYSTEM_GEN ("C$COPY", 3, cob_acuw_copyfile)
COB_SYSTEM_GEN ("C$FILEINFO", 2, cob_acuw_file_info)
COB_SYSTEM_GEN ("C$DELETE", 2, cob_acuw_file_delete)
COB_SYSTEM_GEN ("C$TOUPPER", 2, CBL_TOUPPER)
COB_SYSTEM_GEN ("C$TOLOWER", 2, CBL_TOLOWER)
COB_SYSTEM_GEN ("C$JUSTIFY", 1, cob_acuw_justify)
COB_SYSTEM_GEN ("CBL_OC_NANOSLEEP", 1, cob_oc_nanosleep)

/**/

Note the “SYSTEM”. This CALL sends a command string to the shell. It acts as a wrapper to the standard C library “system” call. “SYSTEM” removes any trailing spaces from the argument and appends the null terminator required for the C library “system” call. While shell access opens yet another powerful door for the OpenCOBOL programmer, diligent delevop