The original principal developers of GnuCOBOL were Keisuke Nishida and Roger While. Since then many others of the GnuCobol community are directly involved in it’s development at any one time.
This document is intended to serve as a full-function reference and user’s guide suitable for both those readers learning COBOL for the first time as usage as a training tool, as well as those already familiar with some dialect of the COBOL language.
A separate manual exists that just contains the details of the GNUCobol implementation which is designed strictly for experienced Cobol programmers taken from this guide. This document (GnuCobol Quick Reference) does NOT contain any training subject matter.
Caution. Although this document is for version 2.2 of the compiler, it also includes a description of the functions of the RWCS (Report Writer module) which is not included in the compiler version 2.2. Please see availability notes on this at 1.3.13.
If you like to hold a book in your hands, I strongly recommend "Murach’s Structured COBOL", by Mike Murach, Anne Prince and Raul Menendez (2000) - ISBN 9781890774059. Mike Murach and his various writing partners have been writing outstanding COBOL textbooks for decades, and this text is no exception. It’s an excellent book for those familiar with the concepts of programming in other languages, but unfamiliar with COBOL.
Would you prefer a web-based tutorial? Try the University of Limerick (Ireland) COBOL web site - ‘http://www.csis.ul.ie/cobol/’.
COBOL, first introduced to the programming public in 1959, was the very first programming language to become standardized (in 1960). This meant that a standard-compliant COBOL program written on computer "A" made by company "B" would be able to be compiled and executed on computer "X" made by company "Y" with very few, if any, changes. This may not seem like such a big deal today, but it was a radical departure from all programming languages that came before it and even many that came after it.
The name COBOL actually says it all — COBOL is an acronym that stands for "(CO)mmon (B)usiness (O)riented (L)anguage". Note the fact that the word "common" comes before all others. The word "business" is a close second. Therein lies the key to Cobol’s success.
Just because COBOL doesn’t traditionally support objects, classes, and the like doesn’t mean that its "procedural" approach to computing isn’t valuable — after all, it runs 70% of the worlds business transactions, and does so:
Today’s IT managers and business leaders are faced with a challenging dilemma — how do you maintain the enormous COBOL code base that is still running their businesses when academia has all but abandoned the language they need their people to use to keep the wheels rolling? The problem is compounded by the fact that those programmers that are skilled in COBOL are retiring and taking their knowledge with them. In some markets, this appears to be having an inflationary effect on the cost of resources (COBOL programmers) whose supply is becoming smaller and smaller. The pressure to update applications to make use of more up-to-date graphical user interfaces is also perceived as a reason to abandon COBOL in favour of GUI-friendly languages such as Java.
Businesses are addressing the COBOL challenge in different ways:
It’s probably a true that an IT professional can no longer afford to allow COBOL to be the only wrench in their toolbox, but with a massive code base still in production now and for the foreseeable future, adding COBOL to a multi-lingual curriculum vitae (CV) and/or resume (yes — they ARE different) is not a bad thing at all. Knowing COBOL as well as the language du-jour will make you the smartest person in the room when the discussion of migrating the current "legacy" environment to a "modern" implementation comes around.
You’ll find COBOL an easy language to learn and a FAR EASIER language to master than many of the "modern" languages.
The whole reason you’re reading this is that you’ve discovered GnuCOBOL — another implementation of COBOL in addition to those mentioned earlier. The distinguishing characteristic of GnuCOBOL versus those others is that GnuCOBOL is FREE open-source and therefore FREE to obtain and use. It is community-enhanced and community-supported. Later in this document (see So What is GnuCOBOL?), you’ll begin to learn more about this COBOL implementation’s capabilities.
The amount of programming necessary to accomplish a given task — including rework needed by any errors found during testing (testing is sometimes jokingly defined as: "that time during which an application is actually in production, allowing users to discover the problems") is the measure of programmer productivity. Anything that reduces that effort will therefore reduce the time spent in such activities therefore reducing the expense of same. When the expense of programming is reduced, programmer productivity is increased.
Sometimes the quest for improved programmer productivity (and therefore reduced programming expense) has taken the form of introducing new features in programming languages, or even new languages altogether. Sometimes it has resulted in new ways of using the existing languages.
While many technological and procedural developments have made evolutionary improvements to programmer productivity, each of the following three events has been responsible for revolutionary improvements:
The reality is, however, that good programmers have been practising code re-usability for more than a half-century. Up until recently, COBOL programmers have had some of the best code re-usability tools available — they’ve been doing it with copybooks and subprograms rather than classes, methods and attributes but the net results have been similar. With the COBOL2002 standard and proposed COBOL 20XX standard, the COBOL programming language has become just as "object-oriented" as the "modern" languages, while preserving the ability to support, modify, compile and execute "legacy" COBOL programs as well.
While GnuCOBOL supports few of the OOP programming constructs defined by the COBOL2002 and COBOL20xx standards, it supports every aspect of the ANSI 85 standard and therefore fully meets the needs of points #1 and #2, above. With it’s supported feature set (see So What is GnuCOBOL?), it provides significant programmer productivity capabilities.
The MinGW approach is a personal favourite with the author of this manual because it creates a GnuCOBOL compiler and runtime library that require only a single MinGW DLL to be available for the GnuCOBOL compiler, runtime library and user programs. That DLL is freely distributable under the terms of the GNU General Public License. A MinGW build of GnuCOBOL fits easily on and runs from a 128MB flash drive with no need to install any software onto the Windows computer that will be using it. Some functionality of the language, dealing with the sharing of files between concurrently executing GnuCOBOL programs and record locking on certain types of files, is sacrificed however as the underlying operating system routines needed to implement them aren’t available to Windows and aren’t provided by MinGW. The current version for MinGW is available at the download link along with various other platforms at the GnuCobol download website (https://sourceforge.net/projects/open-cobol/files/gnu-cobol/2.0/).
GnuCOBOL has also been built as a truly native Windows application utilizing Microsoft’s freely-downloadable Visual Studio Express package to provide the C compiler and linker/loader. This approach does not lend itself well to a "portable" distribution.
The GnuCOBOL compiler generates C code from your COBOL programs; that C code is then automatically compiled and linked using your system’s C compiler (typically, but not limited to, "gcc").
GnuCOBOL fully supports much of the ANSI 85 standard for COBOL (the only major exclusion is the Communications Module) and also supports some of the components of the COBOL2002 standard, such as theSCREEN SECTION(see SCREEN SECTION), table-basedSORT(see Table SORT) and user-defined functions.
The GnuCOBOL language specification defines over 900 ’Reserved Words’
Programmers may use a reserved word as part of a word they are creating themselves, but may not create their own word as an exact duplicate (without regard to case) of a COBOL reserved word. Note that a reserved word includes all classes, such as intrinsic functions, mnemonics names, system routines and reserved words.
See Appendix B - Reserved Word List, for a complete list of GnuCOBOL reserved words for the current release.
User-defined words may be composed from the characters "A" through "Z" (upper- and/or lower-case), "0" through "9", dash ("-")
Other programming language provide the programmer with a similar capability of creating their own words (names) for parts of a program; COBOL is somewhat unusual when compared to other languages in that user-defined words may start with a digit.
With the exception of logic procedure names, which may consist entirely of nothing but digits, user-defined words must contain at least one letter.
The only time the case used does matter is within quoted character strings, where character values will be exactly as coded.
By convention throughout this document, COBOL reserved words will be shown entirely in UPPER-CASE while those words that were created by a programmer will be represented by tokens in mixed or lower case.
This isn’t a bad practice to use in actual programs, as it leads to programs where it is much easier to distinguish reserved words from user-defined ones!
Here are two different "Hello World" applications — one written in Java and the second in GnuCOBOL. First, the Java version:
Class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
And here is the same program, written in GnuCOBOL:
IDENTIFICATION DIVISION.
PROGRAM-ID. HelloWorld.
PROCEDURE DIVISION.
DISPLAY "Hello World!".
Both of the above programs could have been written on a single line, if desired, and both languages allow a programmer to use (or not use) indentation as they see fit to improve program readability. Sounds like a tie so far.
Let’s look at how much more "wordy" COBOL is than Java. Count the characters in the two programs. The Java program has 95 (not counting carriage returns and any indentation). The COBOL program has 89 (again, not counting carriage returns and indentation)! Technically, it could have been only 65 because theIDENTIFICATION DIVISION.header is actually optional. Clearly, "Hello World" doesn’t look any more concise in Java than it does in COBOL.
Let’s look at a different problem. Surely a program that asks a user to input a positive integer, generates the sum of all positive integers from 1 to that number and then prints the result will be MUCH shorter and MUCH easier to understand when coded in Java than in COBOL, right?
You can be the judge. First, the Java version:
import java.util.Scanner;
public class sumofintegers {
public static void main(String[] arg) {
System.out.println("Enter a positive integer");
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
int sum=0;
for (int i=1;i<=n;i++) {
sum+=i;
}
System.out.println("The sum is "+sum);
}
}
And now for the COBOL version:
IDENTIFICATION DIVISION.
PROGRAM-ID. SumOfIntegers.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 n BINARY-LONG.
01 i BINARY-LONG.
01 sum BINARY-LONG VALUE 0.
PROCEDURE DIVISION.
DISPLAY "Enter a positive integer"
ACCEPT n
PERFORM VARYING i FROM 1 BY 1 UNTIL i > n
ADD i TO sum
END-PERFORM
DISPLAY "The sum is " sum.
My familiarity with COBOL may be prejudicing my opinion, but it doesn’t appear to me that the Java code is any simpler than the COBOL code. In case you’re interested in character counts, the Java code comes in at 278 (not counting indentation characters). The COBOL code is 298 (274 without theIDENTIFICATION DIVISION.header).
Despite what you’ve seen here, the more complex the programming logic being implemented, the more concise the Java code will appear to be, even compared to 2002-standard COBOL. That conciseness comes with a price though — program code readability. Java (or C or C++ or C#) programs are generally intelligible only to trained programmers. COBOL programs can, however, be quite understandable by non-programmers. This is actually a side-effect of the "wordiness" of the language, where COBOL statements use natural English words to describe their actions. This inherent readability has come in handy many times throughout my career when I’ve had to learn obscure business (or legal) processes by reading the COBOL program code that supports them.
The "modern" languages, like Java, also have their own "boilerplate" infrastructure overhead that must be coded in order to write the logic that is necessary in the program. Take for example thepublic static void main(String[] arg)andimport java.util.Scanner;statements. The critics tend to forget about this when they criticize COBOL for it’s structural "overhead".
When it first was developed, Cobol’s easily-readable syntax made it profoundly different from anything that had been seen before. For the first time, it was possible to specify logic in a manner that was — at least to some extent — comprehensible even to non-programmers. Take for example, the following code written in FORTRAN — a language developed only a year before COBOL:
EXT = PRICE * IQTY
INVTOT = INVTOT + EXT
With its original limitation on the length of variable names (one- to six-character names comprised of a letter followed by up to five letters and/or digits), it’s implicit rule that variable were automatically created as real (floating-point) unless their name started with a letter in the range I-N, and its use of algebraic notation to express actions being taken, FORTRAN wasn’t a particularly readable language, even for programmers. Compare this with the equivalent COBOL code:
MULTIPLY price BY quantity GIVING extended-amount
ADD extended-amount TO invoice-total
Clearly, even a non-programmer could at least conceptually understand what was going on! Over time, languages like FORTRAN evolved more robust variable names, and COBOL introduced a more formula-based syntactical capability for arithmetic operations, but FORTRAN was never as readable as COBOL.
Because of its inherent readability, I would MUCH rather be handed an assignment to make significant changes to a COBOL program about which I know nothing than to be asked to do the same with a C, C++, C# or Java program.
Those that argue that it is too boring / wasteful / time-consuming / insulting (pick one) to have to code a COBOL program "from scratch" are clearly ignorant of the following facts:
Each division may consist of a variety of sections and each section consists of one or more paragraphs. A paragraph consists of sentences, each of which consists of one or more statements.
This hierarchical structure of program components standardizes the composition of all COBOL programs. Much of this manual describes the various divisions, sections, paragraphs and statements that may comprise any COBOL program.
Today’s current programming languages have a statement (usually, this statement is named "import", "include" or "#include") that performs this same function. What makes the COBOL copybook feature different than the "include" facility in newer languages, however, is the fact that theCOPYstatement can edit the imported source code as it is being copied. This capability makes copybook libraries extremely valuable to making code reusable.
COBOL introduced the concept of structured data. The principle of structured data in COBOL is based on the idea of being able to group related and contiguously-allocated data items together into a single aggregate data item, called a ’Group Item’
A data item that isn’t itself formed from other data items is referred to in COBOL as an ’Elementary Item’
ORGANIZATION LINE SEQUENTIAL These are files with the simplest of all internal structures. Their contents are structured simply as a series of identically- or differently-sized data records, each terminated by a special end-of-record delimiter character. An ASCII line-feed character (hexadecimal 0A) is the end-of-record delimiter character used by any UNIX or pseudo-UNIX (MinGW, Cygwin, OSX) GnuCOBOL build. A truly native Windows build would use a carriage-return, line-feed (hexadecimal 0D0A) sequence.
Records must be read from or written to these files in a purely sequential manner. The only way to read (or write) record number 100 would be to have read (or written) records number 1 through 99 first.
When the file is written to by a GnuCOBOL program, the delimiter sequence will be automatically appended to each data record as it is written to the file. AWRITE(see WRITE) to this type of file will be done as if aBEFORE ADVANCING 1 LINEclause were specified on theWRITE if noADVANCINGclause is coded.
When the file is read, the GnuCOBOL runtime system will strip the trailing delimiter sequence from each record. The data will be padded (on the right) with spaces if the data just read is shorter than the area described for data records in the program. If the data is too long, it will be truncated and the excess will be lost.
These files should not be defined to contain any exact binary data fields because the contents of those fields could inadvertently have the end-of-record sequence as part of their values — this would confuse the runtime system when reading the file, and it would interpret that value as an actual end-of-record sequence.
LINE ADVANCINGThese are files with an internal structure similar to that of a line sequential file. These files are defined (without an explicitORGANIZATIONspecification) using theLINE ADVANCINGclause on theirSELECTstatement (see SELECT).
When this kind of file is written to by a GnuCOBOL program, an end-of-record delimiter sequence will be automatically added to each data record as it is written to the file. AWRITEto this type of file will be done as if anAFTER ADVANCING 1 LINEclause were specified on theWRITE if noADVANCINGclause is coded.
Like line sequential files, these files should not be defined to contain any exact binary data fields because the contents of those fields could inadvertently have the end-of-record sequence as part of their values — this would confuse the runtime system when reading the file, and it would interpret that value as an actual end-of-record sequence.
ORGANIZATION SEQUENTIAL These files also have a simple internal structure. Their contents are structured simply as an arbitrarily-long sequence of data characters. This sequence of characters will be treated as a series of fixed-length records simply by logically splitting the sequence of characters up into fixed-length segments, each as long as the maximum record size defined in the program. There are no special end-of-record delimiter characters in the file and when the file is written to by a GnuCOBOL program, no delimiter sequence is appended to the data.
Records in this type of file are all the same physical length, except possibly for the very last record in the file, which may be shorter than the others. If variable-length logical records are defined to the program, the space occupied by each physical record in the file will occupy the space described by the longest record description in the program.
So, if a file contains 1275 characters of data, and a program defines the structure of that file as containing 100-character records, then the file contents will consist of twelve (12) 100-character records with a final record containing only 75 characters.
It would appear that it should be possible to locate and process any record in the file directly simply by calculating its starting character position based upon the program-defined record size. Even so, however, records must be still be read or written to these files in a purely sequential manner. The only way to read (or write) record number 100 would be to have read (or written) records number 1 through 99 first.
When the file is read, the data is transferred into the program exactly as it exists in the file. In the event that a short record is read as the very last record, that record will be padded (to the right) with spaces.
Care must be taken that programs reading such a file describe records whose length is exactly the same as that used by the program that created the file. For example, the following shows the contents of aSEQUENTIALfile created by a program that wrote five 6-character records to it. The "A", "B", … values reflect the records that were written to the file:
Now, assume that another program reads this file, but describes 10-character records rather than 6. Here are the records that program will read:
There may be times where this is exactly what you were looking for. More often than not, however, this is not desirable behaviour. Suggestion: use a copybook to describe the record layouts of any file; this guarantees that multiple programs accessing that file will "see" the same record sizes and layouts by coding aCOPYstatement (see COPY) to import the record layout(s) rather than hand-coding them.
These files can contain exact binary data fields. This is possible because — since there is no character sequence that constitutes an end-of-record delimiter — the contents of record fields are irrelevant to the reading process.
ORGANIZATION RELATIVE The contents of these files consist of a series of fixed-length data records prefixed with a four-byte record header. The record header contains the length of the data, in bytes. The byte-count does not include the four-byte record header.
Records in this type of file are all the same physical length. If variable-length logical records are defined to the program, the space occupied by each physical record in the file will occupy the maximum possible space, and the logical record length field will contain the number of bytes of data in the record that are actually in use.
This file organization was defined to accommodate either sequential or random processing. With aRELATIVEfile, it is possible to read or write record 100 directly, without having to have first read or written records 1-99. The GnuCOBOL runtime system uses the program-defined maximum record size to calculate a relative byte position in the file where the record header and data begin, and then transfers the necessary data to or from the program.
When the file is written by a GnuCOBOL program, no delimiter sequence is appended to the data, but a record-length field is added to the beginning of each physical record.
When the file is read, the data is transferred into the program exactly as it exists in the file.
Care must be taken that programs reading such a file describe records whose length is exactly the same as that used by the programs that created the file. It won’t end well if the GnuCOBOL runtime library interprets a four-byte ASCII character string as a record length when it transfers data from the file into the program!
Suggestion: use a copybook to describe the record layouts of any file; this guarantees that multiple programs accessing that file will "see" the same record sizes and layouts by coding aCOPYstatement (see COPY) to import the record layout(s) rather than hand-coding them.
These files can contain exact binary data fields. The contents of record fields are irrelevant to the reading process as there is no end-of-record delimiter.
ORGANIZATION INDEXED This is the most advanced file structure available to GnuCOBOL programs. It’s not possible to describe the physical structure of such files because that structure will vary depending upon which advanced file-management facility was included into the GnuCOBOL build you will be using (Berkeley Database [BDB], VBISAM, etc.). We will — instead — discuss the logical structure of the file.
There will be multiple structures stored for anINDEXEDfile. The first will be a data component, which may be thought of as being similar to the internal structure of a relative file. Data records may not, however, be directly accessed by their record number as would be the case with a relative file, nor may they be processed sequentially by their physical sequence in the file.
The remaining structures will be one or more index components. An index component is a data structure that (somehow) enables the contents of a field, called a primary key, within each data record (a customer number, an employee number, a product code, a name, etc.) to be converted to a record number so that the data record for any given primary key value can be directly read, written and/or deleted. Additionally, the index data structure is defined in such a manner as to allow the file to be processed sequentially, record-by-record, in ascending sequence of the primary key field values. Whether this index structure exists as a binary-searchable tree structure (b-tree), an elaborate hash structure or something else is pretty much irrelevant to the programmer — the behaviour of the structure will be as it was just described. The actual mechanism used will depend upon the advanced file-management package was included into your GnuCOBOL implementation when it was built.
The runtime system will not allow two records to be written to an indexed file with the same primary key value.
The capability exists for an additional field to be defined as what is known as an alternate key. Alternate key fields behave just like primary keys, allowing both direct and sequential access to record data based upon the alternate key field values, with one exception. That exception is the fact that alternate keys may be allowed to have duplicate values, depending upon how the alternate key field is described to the GnuCOBOL compiler.
There may be any number of alternate keys, but each key field comes with a disk space penalty as well as an execution time penalty. As the number of alternate key fields increases, it will take longer and longer to write and/or modify records in the file.
These files can contain exact binary data fields. The contents of record fields are irrelevant to the reading process as there is no end-of-record delimiter.
All files are initially described to a GnuCOBOL program using aSELECTstatement (see SELECT). In addition to defining a name by which the file will be referenced within the program, theSELECTstatement will specify the name and path by which the file will be known to the operating system along with its organization, locking and sharing attributes.
A file description in theFILE SECTION(see FILE SECTION) will define the structure of records within the file, including whether or not variable-length records are possible and — if so — what the minimum and maximum length might be. In addition, the file description entry can specify file I/O block sizes.
The first can search a table sequentially, stopping only when either a table entry matching one of any number of search conditions is found, or when all table entries have been checked against the search criteria and none matched any of those criteria.
The second can perform an extremely fast search against a table sorted by and searched against a key field contained in each table entry. The algorithm used for such a search is a binary search (also known as a half-interval search). This algorithm ensures that only a small number of entries in the table need to be checked in order to find a desired entry or to determine that the desired entry doesn’t exist in the table. The larger the table, the more effective this search becomes. For example, a binary search of a table containing 32,768 entries will be able to locate a particular entry or determine the entry doesn’t exist by looking at no more than fifteen (15) entries! The algorithm is explained in detail in the documentation of theSEARCH ALLstatement (see SEARCH ALL).
Finally, COBOL has the ability to perform in-place sorts of the data that is found in a table.
A companion statement —MERGE(see MERGE) — can combine the contents of multiple files together, provided those files are all pre-sorted in a similar manner according to the same key structure. The resulting output will consist of the contents of all of the input files, merged together and sequenced according to the common key structure(s). The output generated by aMERGEstatement may be written automatically to one or more output files or may be processed internally by the program.
A special form of theSORTstatement also exists just to sort the data that resides in a table. This is particularly useful if you wish to useSEARCH ALLagainst the table.
COBOL is no exception, although it does include some very powerful string manipulation capabilities; GnuCOBOL actually has even more string-manipulation capabilities than many other COBOL implementations. The following summarizes GnuCOBOL’s string-processing capabilities:
Concatenate two or more strings:
CONCATENATEintrinsic function (see CONCATENATE). STRINGstatement (see STRING). Conversion of a numeric time or date to a formatted character string:
LOCALE-TIMEintrinsic function (see LOCALE-TIME). LOCALE-DATEintrinsic function (see LOCALE-DATE). Convert a binary value to its corresponding character in the program’s character set:
CHARintrinsic function (see CHAR). Add 1 to argument before invoking the function; the description of theCHARintrinsic function presents a technique utilizing theMOVEstatement that will accomplish the same thing without the need of adding 1 to the numeric argument value first. Convert a character string to lower-case:
LOWER-CASEintrinsic function (see LOWER-CASE). C$TOLOWERbuilt-in system subroutine (see C$TOLOWER). CBL_TOLOWERbuilt-in system subroutine (see CBL_TOLOWER). Convert a character string to upper-case:
UPPER-CASEintrinsic function (see UPPER-CASE). C$TOUPPERbuilt-in system subroutine (see C$TOUPPER). CBL_TOUPPERbuilt-in system subroutine (see CBL_TOUPPER). Convert a character string to only printable characters:
C$PRINTABLEbuilt-in system subroutine (see C$PRINTABLE). Convert a character to its numeric value in the program’s character set:
ORDintrinsic function (see ORD). Subtract 1 from the result; the description of theORDintrinsic function presents a technique utilizing theMOVEstatement that will accomplish the same thing without the need of adding 1 to the numeric argument value first. Count occurrences of sub strings in a larger string:
INSPECTstatement (see INSPECT) with theTALLYINGclause. Decode a formatted numeric string back to a numeric value:
Determine the length of a string or data-item capable of storing strings:
LENGTHintrinsic function (see LENGTH). BYTE-LENGTHintrinsic function (see BYTE-LENGTH). Extract a sub string from a string based on its starting character position and length:
Format a numeric item for output, including thousands-separators ("," in the USA), currency symbols ("$" in the USA), decimal points, credit/Debit Symbols, Leading Or Trailing Sign Characters:
MOVEstatement (see MOVE) with picture-symbol editing applied to the receiving field: Justification (left, right or centred) of a string field:
C$JUSTIFYbuilt-in system subroutine (see C$JUSTIFY). Monoalphabetic substitution of one or more characters in a string with different characters:
INSPECTstatement (see INSPECT) with theCONVERTING TRANSFORMstatement (see TRANSFORM). SUBSTITUTEintrinsic function (see SUBSTITUTE). SUBSTITUTE-CASEintrinsic function (see SUBSTITUTE-CASE). Parse a string, breaking it up into sub strings based upon one or more delimiting character sequences1:
UNSTRINGstatement (see UNSTRING). Removal of leading or trailing spaces from a string:
TRIMintrinsic function (see TRIM). Substitution of a single sub string with another of the same length, based upon the sub strings starting character position and length:
MOVEstatement (see MOVE) with a reference modifier on the "receiving" field (see Reference Modifiers). Substitution of one or more sub strings in a string with replacement sub strings of the same length, regardless of where they occur:
INSPECTstatement (see INSPECT) with aREPLACINGclause. SUBSTITUTEintrinsic function (see SUBSTITUTE). SUBSTITUTE-CASEintrinsic function (see SUBSTITUTE-CASE). Substitution of one or more sub strings in a string with replacement sub strings of a potentially different length, regardless of where they occur:
SUBSTITUTEintrinsic function (see SUBSTITUTE). SUBSTITUTE-CASEintrinsic function (see SUBSTITUTE-CASE). These features allow fields to be displayed at specific row/column positions, various colors and video attributes to be assigned to screen fields and the pressing of specific function keys (F1, F2, …) to be detectable. All of this takes place through the auspices of theSCREEN SECTION(see SCREEN SECTION) and special formats of theACCEPTstatement (see ACCEPT) and theDISPLAYstatement (see DISPLAY).
The COBOL2002 standard, and therefore GnuCOBOL, only covers textual user interface (TUI) screens (those comprised of ASCII characters presented using a variety of visual attributes) and not the more-advanced graphical user interface (GUI) screen design and processing capabilities built into most modern operating systems. There are subroutine-based packages available that can do full GUI presentation — most of which may be called by GnuCOBOL programs, with a moderate research time investment (Tcl/Tk, for example) — but none are currently included with GnuCOBOL.
A Sample Screen Produced by a GnuCOBOL Program:
================================================================================
GCic (2014/01/02 11:24) GnuCOBOL 2.1 23NOV2013 Interactive Compilation
+------------------------------------------------------------------------------+
: Filename: GCic.cbl :
: Folder: E:\Programs\GCic\2013-11-23 :
+------------------------------------------------------------------------------+
Set/Clr Switches Via F1-F9; Set Config Via F12; ENTER Key Compiles; ESC Quits
+------------------------------------------------------------------------------+
: F1 Assume WITH DEBUGGING MODE F6 >"FUNCTION" Is Optional : Current :
: F2 Procedure+Statement Trace F7 >Enable All Warnings : Config: :
: F3 Make a Library (DLL) F8 Source Is Free-Format : DEFAULT :
: F4 Execute If Compilation OK F9 >No COMP/BINARY Truncation : :
: F5 Listing Off : :
+------------------------------------------------------------------------------+
Extra "cobc" Switches, If Any ("-save-temps=xxx" Prevents Listings):
+------------------------------------------------------------------------------+
: ____________________________________________________________________________ :
: ____________________________________________________________________________ :
+------------------------------------------------------------------------------+
Program Execution Arguments, If Any:
+------------------------------------------------------------------------------+
: ____________________________________________________________________________ :
: ____________________________________________________________________________ :
+------------------------------------------------------------------------------+
GCic for Windows/MinGW Copyright (C) 2009-2014, Gary L. Cutler, GPL
================================================================================
The above screen was produced by the GnuCOBOL Interactive Compiler, or GCic. See GCic in GnuCOBOL Sample Programs, for the source and cross-reference listing of this program. PDF versions of this document will include an actual graphical image of this sample screen.
Screens are defined in the screen section of the data division. Once defined, screens are used at run-time via theACCEPTandDISPLAYstatements.
GnuCOBOL supports the following visual attribute specifications in theSCREEN SECTION(see SCREEN SECTION):
Eight (8) different colors may be specified for both the background (screen) and foreground (text) color of any row/column position on the screen. Colors are specified by number, although a copybook supplied with all GnuCOBOL distributions ("screenio.cpy") defines COB-COLOR-xxxxxx names for the various colors so they may be specified as a more meaningful name rather than a number. The eight colors, by number, with the constant names defined in screenio.cpy, are as follows:
There are three possible brightness levels supported for text — lowlight (dim), normal and highlight (bright). Not all GnuCOBOL implementations will support all three (some treat lowlight the same as normal). The deciding factor as to whether two or three levels are supported lies with the version of the "curses" package that is being used. This is a utility screen-IO package that is included into the GnuCOBOL run-time library when the GnuCOBOL software is built.
As a general rule of thumb, Windows implementations support two levels while Unix ones support all three.
This too is a video feature that is dependent upon the "curses" package built into your version of GnuCOBOL. If blinking is enabled in that package, text displayed in fields defined in the screen section as being blinking will endlessly cycle between the brightest possible setting (highlight) and an "invisible" setting where the text color matches that of the field background color. A Windows build, which generally uses the "pcurses" package, will uses a brighter-than-normal background color to signify "blinking".
This video attribute simply swaps the foreground and background colors and display options.
It is possible, if supported by the "curses" package being used, to draw borders on the top, left and/or bottom edges of a field.
If desired, screen fields used as input fields may defined as "secure" fields, where each input character (regardless of what was actually typed) will appear as an asterisk (*) character. The actual character whose key was pressed will still be stored into the field in the program, however. This is very useful for password or account number fields.
Input fields may have any character used as a fill character. These fill characters provide a visual indication of the size of the input field, and will automatically be transformed into spaces when the input field is processed by the program. If no such character is defined for an input field, an underscore ("_") will be assumed.
SORTstatement (see SORT) keys — have changed. This is known as a control break. The RWCS can automatically perform the following reporting actions when a control break occurs: TheREPORT SECTION(see REPORT SECTION) documentation explores the description of reports and thePROCEDURE DIVISION(see PROCEDURE DIVISION) chapter documents the various language statements that actually produce reports. Before reading these, you might find it helpful to read Report Writer Usage Notes, which is dedicated to putting the pieces together for you.
SPACES ZERO VALUE(see VALUE) clause in their definition will be initialized to that specific value. The various sections of the data division each have their own rules as to when the actions described above will occur — consult the documentation on those sections for additional information.
These default initialization rules can vary quite substantially from one COBOL implementation to another. For example, it is quite common for data division storage to be initialized to all binary zeros except for those data items whereVALUEclauses are present. Take care when working with applications originally developed for another COBOL implementation to ensure that GnuCOBOL’s default initialization rules won’t prove disruptive.
INITIALIZEstatement (see INITIALIZE) to initialise any group or elementary data item at any time. This statement provides far more initialization options than just the simple rules stated above. ALLOCATEstatement (see ALLOCATE) statement is used to allocate a data item or to simply allocate an area of storage of a size specified on theALLOCATE that allocation may occur with or without initialization, as per the programmer’s needs. MANDATORY-RESERVED-WORD~~~~~~~~~~~~~~~~~~~~~~~Reserved words of the COBOL language will appear in UPPER-CASE. When they appear underlined, as this one is, they are required reserved words.
OPTIONAL-RESERVED-WORDWhen reserved words appear without underlining, as this one is, they are optional; such reserved words are available in the language syntax merely to improve readability — their presence or absence has no effect upon the program.
ABBREVIATION~~~~When only a portion of a reserved word is underlined, it indicates that the word may either be coded in its full form or may be abbreviated to the portion that is underlined.
substitutable-itemsGeneric terms representing user-defined substitutable items will be shown entirely in lower-case in syntax diagrams. When such items are referenced in text, they will appear as <substitutable-items>.
Complex-Syntax-ClauseItems appearing in Mixed Case within a syntax diagram represent complex clauses of other syntax elements that may appear in that position. Some COBOL syntax gets quite complicated, and using a convention such as this significantly reduces the complexity of a syntax diagram. When such items are referenced in text, they will appear as <<Complex-Syntax-Clause>>.
[ ]Square bracket meta characters on syntax diagrams document language syntax that is optional. The [] characters themselves should not be coded. If a syntax diagram contains "a [b] c", the "a" and "c" syntax elements are mandatory but the "b" element is optional.
|Vertical bar meta characters on syntax diagrams document simple choices. The | character itself should not be coded. If a syntax diagram contains "a|b|c", exactly one of the items "a", "b" or "c" must be selected.
{ xxxxxx }{ yyyyyy }{ zzzzzz }A vertical list of items, bounded by multiple brace characters, is another way of signifying a choice between a series of items where exactly one item must be selected. This form is used to show choices when one or more of the selections is more complex than just a single word, or when there are too many choices to present horizontally with "|" meta characters.
| xxxxxx || yyyyyy || zzzzzz |A vertical list of items, bounded by multiple vertical bar characters, signifies a choice between a series of items where one or more of the choices could be selected.
...The ... meta character sequence signifies that the syntax element immediately preceding it may be repeated. The ... sequence itself should not be coded. If a syntax diagram containsa b... c syntax element "a" must be followed by at least one "b" element (possibly more) and the entire sequence must be terminated by a "c" syntax element.
{ }The braces ({}) meta characters may be used to group a sequence of syntax elements together so that they may be treated as a single entity. The {} characters themselves should not be coded. These are typically used in combination with the "|" or "..." meta characters.
$*^()-+=:"'<,>./Any of these characters appearing within a syntax diagram are to be interpreted literally, and are characters that must be coded — where allowed — in the statement whose format is being described. Note that a "." character is a literal character that must be coded on a statement whereas a "..." symbol is the meta character sequence described above.
As of the COBOL2002 standard, a second mode now exists for COBOL source code statements — in this mode of operation, COBOL statements may each be up to 255 characters long, with no specific requirements as to what should appear in which columns.
Of course, in keeping with the long-standing COBOL tradition of maintaining backwards compatibility with older standards, programmers (and, of course, compliant COBOL compilers) are capable of working in either mode. It is even possible to switch back and forth in the same program. The terms ’Fixed Format Mode’
The GnuCOBOL compiler (cobc) supports both of these source line format modes, defaulting to Fixed Format Mode lacking any other information.
The compiler can be instructed to operate in either mode in any of the following four ways:
-fixedswitch SOURCEFORMAT AS FIXEDandSOURCEFORMAT AS FREEclauses of the>>SETCDF directive (see >>SET) within your source code to switch to Fixed or Free Format Mode, respectively. >>FORMAT IS FIXEDandFORMAT IS FREEclauses of the>>DEFINECDF directive (see >>DEFINE) within your source code to switch to Fixed or Free Format Mode, respectively. >>SOURCECDF directive (see >>SOURCE) to switch to Free Format Mode >>SOURCE FORMAT IS FREE or Fixed Format Mode >>SOURCE FORMAT IS FIXED Using methods 2-4 above, you may switch back and forth between the two formats at will.
The last three options above are all equivalent; all three are supported by GnuCOBOL so that source code compatibility may be maintained with a wide variety of other COBOL implementations. With all three, if the compiler is currently in Fixed Format Mode, the>>must begin in column 8 or beyond, provided no part of the directive extends past column 72. If the compiler is currently in Free Format Mode, the>>may appear in any column, provided no part of the directive extends past column 255.
Depending upon which source format mode the compiler is in, you will need to follow various rules for the format mode currently in effect. These rules are presented in the upcoming paragraphs.
The following discussion presents the various components of every GnuCOBOL source line record when the compiler is operating in Fixed Format Mode. Remember that this is the default mode for the GnuCOBOL compiler.
Historically, back in the days when punched-cards were used to submit COBOL program source to a COBOL compiler, this part of a COBOL statement was reserved for a six-digit sequence number. While the contents of this area are ignored by COBOL compilers, it existed so that a program actually punched on 80-character cards could — if the card deck were dropped on the floor — be run through a card sorter machine and restored to it’s proper sequence. Of course, this isn’t necessary today; if truth be told, it hasn’t been necessary for a long time.
See Marking Changes in Programs, for discussion of a valuable use to which the sequence number area may be put today.
Column 7 serves as an indicator in which one of five possible values will appear — space,D(ord,-(dash),/or* The meanings of these characters are as follows:
No special meaning — this is the normal character that will appear in this area.
The line contains a valid GnuCOBOL statement that is normally treated as a comment unless the program is being compiled in debugging mode.
The line is a comment.
The line is a comment that will also force a page eject in the compilation listing. While GnuCOBOL will honour such a line as a comment, it will not form-feed any generated listing.
The line is a continuation of the previous line. These are needed only when an alphanumeric literal (quoted character string), reserved word or user-defined word are being split across lines.
Language DIVISION, SECTION and paragraph section headers must begin in Area A, as must the level numbers 01, 77 in data description entries and the "FD" and "SD" file and SORT description headers.
All other COBOL programming language components are coded in these columns.
This is another obsolete area of COBOL statements. This part of every statement also hails back to the day when programs were punched on cards; it was expected that the name of the program (or at least the first 8 characters of it) would be punched here so that — if a dropped COBOL source deck contained more than one program — that handy card sorter machine could be used to first separate the cards by program name and then sort them by sequence number. Today’s COBOL compilers (including GnuCOBOL) simply ignore anything past column 72.
See Marking Changes in Programs, for discussion of a valuable use to which the program name area may be put today.
[ IDENTIFICATION DIVISION. ]
~~~~~~~~~~~~~~~~~~~~~~~
PROGRAM-ID|FUNCTION-ID. name-1 [ Program-Options ] .
~~~~~~~~~~ ~~~~~~~~~~~
[ ENVIRONMENT DIVISION. ]
~~~~~~~~~~~ ~~~~~~~~
[ CONFIGURATION SECTION. ]
~~~~~~~~~~~~~ ~~~~~~~
[ SOURCE-COMPUTER. Compilation-Computer-Specification . ]
~~~~~~~~~~~~~~~
[ OBJECT-COMPUTER. Execution-Computer-Specification . ]
~~~~~~~~~~~~~~~
[ REPOSITORY. Function-Specification... . ]
~~~~~~~~~~
[ SPECIAL-NAMES. Program-Configuration-Specification . ]
~~~~~~~~~~~~~
[ INPUT-OUTPUT SECTION. ]
~~~~~~~~~~~~ ~~~~~~~
[ FILE-CONTROL. General-File-Description... . ]
~~~~~~~~~~~~
[ I-O-CONTROL. File-Buffering-Specification... . ]
~~~~~~~~~~~
[ DATA DIVISION. ]
~~~~~~~~~~~~~
[ FILE SECTION. Detailed-File-Description... . ]
~~~~~~~~~~~~
[ WORKING-STORAGE SECTION. Permanent-Data-Definition... . ]
~~~~~~~~~~~~~~~ ~~~~~~~
[ LOCAL-STORAGE SECTION. Temporary-Data-Definition... . ]
~~~~~~~~~~~~~ ~~~~~~~
[ LINKAGE SECTION. Subprogram-Argument-Description... . ]
~~~~~~~ ~~~~~~~
[ REPORT SECTION. Report-Description... . ]
~~~~~~ ~~~~~~~
[ SCREEN SECTION. Screen-Layout-Definition... . ]
~~~~~~ ~~~~~~~
PROCEDURE DIVISION [ { USING Subprogram-Argument... } ]
~~~~~~~~~ ~~~~~~~~ { ~~~~~ }
{ CHAINING Main-Program-Argument... }
~~~~~~~~
[ RETURNING identifier-1 ] .
[ DECLARATIVES. ] ~~~~~~~~~
~~~~~~~~~~~~
[ Event-Handler-Routine... . ]
[ END DECLARATIVES. ]
~~~ ~~~~~~~~~~~~
General-Program-Logic
[ Nested-Subprogram... ]
[ END PROGRAM|FUNCTION name-1 ]
~~~ ~~~~~~~ ~~~~~~~~ Each program consists of up to four ’Divisions’
IDENTIFICATION DIVISION.header is always optional. SOURCE-COMPUTERandOBJECT-COMPUTER for example). Each of these paragraphs serves a specific purpose. If no code is required for the purpose one of the paragraphs serves, the entire paragraph may be omitted. ENVIRONMENT DIVISION.header itself may be omitted. DATA DIVISION.header itself may be omitted. DECLARATIVES.andEND DECLARATIVES.lines may be omitted. END PROGRAMorEND FUNCTIONstatement is optional. END PROGRAMorEND FUNCTIONstatements. The final program in such a source code file need not have anEND PROGRAMorEND FUNCTIONstatement. END PROGRAM A.orEND FUNCTION A.statement. For now, that’s all that will be said about nesting. See Independent vs Contained vs Nested Subprograms, for more information. | Comment Type | Source Mode — Description |
|---|---|
| Blank Lines | FIXED — Blank lines may be inserted as desired. FREE — Blank lines may be inserted as desired. |
| Full-line comments | FIXED — An entire source line will be treated as a comment (and will be ignored by the compiler) by coding an asterisk ("*") in column seven (7). FREE — An entire source line will be treated as a comment (and will be ignored by the compiler) by coding the sequence "*>", starting in any column, as the first non-blank characters on the line. |
| Full-line comments with form-feed | FIXED — An entire source line will be treated as a comment by coding a slash ("/") in column seven (7). Many COBOL compilers will also issue a form-feed in the program listing so that the "/" line is at the top of a new page. The GnuCOBOL compiler does not support this form-feed behaviour. The GnuCOBOL Interactive Compiler, or GCic, does support this form-feed behaviour when it generates program source listings! See GCic in GnuCOBOL Sample Programs, for the source and cross-reference listing (produced by GCic) of this program — you can see the effect of "/" there. FREE — There is no Free Source Mode equivalent to "/". |
| Partial-line comments | FIXED — Any text following the character sequence "*>" on a source line will be treated as a comment. The "*" must appear in column seven (7) or beyond. FREE — Any text following the character sequence "*>" on a source line will be treated as a comment. The "*" may appear in any column. |
| Comments that may be treated as code, typically for debugging purposes |
FIXED — By coding a "D" in column 7 FREE — By specifying the character sequence ">>D" Debugging statements may be compiled either by specifying the-fdebugging-lineswitch
|
An alphanumeric literal is not valid for use in arithmetic expressions unless it is first converted to it’s numeric computational equivalent; there are three numeric conversion intrinsic functions built into GnuCOBOL that can perform this conversion —NUMVAL(see NUMVAL),NUMVAL-C(see NUMVAL-C) andNUMVAL-F(see NUMVAL-F).
Alphanumeric literals may take any of the following forms:
Alphanumeric literals too long to fit on a single line may be continued to the next line in one of two ways:
1 2 3 4 5 6 7123456789012345678901234567890123456789012345678901234567890123456789012301 LONG-LITERAL-VALUE-DEMO PIC X(60) VALUE "This is a long l- "ong literal that- " must be continu- "ed.".
1 2 3 4 5 6 7123456789012345678901234567890123456789012345678901234567890123456789012301 LONG-LITERAL-VALUE-DEMO PIC X(60) VALUE "This is a" &" long literal that must " &"be continued.".
If your program is using Free Format Mode, there’s less need to continue long alphanumeric literals because statements may be as long as 255 characters.
Numeric literals may be split across lines just as alphanumeric literals are, using either of the above techniques and both reserved and user-defined words can be split across lines too (using the first technique). The continuation of numeric literals and user-defined/reserved words is provided merely to provide compatibility with older COBOL versions and programs, but should not be used with new programs — it just makes for ugly-looking programs.
05 FILLER PIC 9(10) VALUE ZEROS. ... MOVE SPACES TO Employee-Name
But this is not:
CALL "SUBPGM" USING SPACES
The following are the GnuCOBOL figurative constants and their respective equivalent values.
ZERO This figurative constant has a value of numeric 0 (zero).ZEROSandZEROESare both synonyms ofZERO
SPACE This figurative constant has a value of one or more space characters.SPACESis a synonym ofSPACE
QUOTE This figurative constant has a value of one or more double-quote characters (").QUOTESis a synonym ofQUOTE
LOW-VALUE This figurative constant has a value of one or more of whatever character occupies the lowest position in the program’s collating sequence as defined in theOBJECT-COMPUTER(see OBJECT-COMPUTER) paragraph or — if no such specification was made — in whatever default character set the program is using (typically, this is the ASCII character set).LOW-VALUESis a synonym ofLOW-VALUE
When the character set in use is ASCII with no collating sequence modifications, theLOW-VALUESfigurative constant value is the ASCII "NUL" character. Because character sets can be redefined, however, you should not rely on this fact — use theNULLfigurative constant instead.
HIGH-VALUE This figurative constant has a value of one or more of whatever character occupies the highest position in the program’s collating sequence as defined in theOBJECT-COMPUTERparagraph or — if no such specification was made — in whatever default character set the program is using (typically, this is the ASCII character set).HIGH-VALUESis a synonym ofHIGH-VALUE
NULL A character comprised entirely of zero-bits (regardless of the programs collating sequence).
Programmers may create their own figurative constants via theSYMBOLIC CHARACTERS(see Symbolic-Characters-Clause) clause of theSPECIAL-NAMES(see SPECIAL-NAMES) paragraph.
The use of comma characters can cause confusion to a COBOL compiler if theDECIMAL POINT IS COMMAclause is used in theSPECIAL-NAMES(see SPECIAL-NAMES) paragraph, as might be the case in Europe. The following statement, which calls a subroutine passing it two arguments (the numeric constants 1 and 2):
CALL "SUBROUTINE" USING 1,2 Would — withDECIMAL POINT IS COMMAin effect — actually be interpreted as a subroutine call with 1 argument (the non-integer numeric literal whose value is 1 and 2 tenths). For this reason, it is best to always follow a comma with a space.
The period character (".")
The rules for where and when periods are needed in the procedure division are somewhat complicated. See Use of Periods, for the details.
LENGTH OF numeric-literal-1 | identifier-1 ~~~~~~
Alphanumeric literals and identifiers may optionally be prefixed with theLENGTH OFclause. The compile-time value generated by this clause will be the number of bytes in the alphanumeric literal or the defined size (in bytes) of the identifier.
OFis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. Here is an example. The following two GnuCOBOL statements both display the same result (27):
01 Demo-Identifier PIC X(27).
...
DISPLAY LENGTH OF "This is a LENGTH OF Example"
DISPLAY LENGTH OF Demo-Identifier
LENGTH OFclause on a literal or identifier reference may generally be used anywhere a numeric literal might be specified, with the following exceptions: Through theCALLstatement, COBOL programs may invoke other COBOL programs serving as subprograms. This is quite similar to cross-program linkage capabilities provided by other languages. In GnuCOBOL’s case, theCALLfacility is powerful enough to be tailored to the point where a GnuCOBOL program can communicate with operating system, database management and run-time library APIs, even if they weren’t written in COBOL themselves. See GnuCOBOL Main Programs CALLing C Subprograms, for an example of how a GnuCOBOL program could invoke a C-language subprogram, passing information back and forth between the two.
The fact that GnuCOBOL supports a full-featured two-way interface with C-language programs means that — even if you cannot access a library API directly — you could always do so via a small C "wrapper" program that isCALLd by a GnuCOBOL program.
When the compiler is operating in Fixed Format Mode, all CDF statements must begin in column eight (8) or beyond.
There are two types of supported CDF statements in GnuCOBOL — Text Manipulation Statements and Compiler Directives.
The CDF text manipulation statementsCOPYandREPLACEare used to introduce new code into programs either with or without changes, or may be used to modify existing statements already in the program. Text manipulation statements are always terminated with a period.
CDF directives, denoted by the presence of a ">>" character sequence as part of the statement name itself, are used to influence the process of program compilation.
Compiler directives are never terminated with a period.
>>CALL-CONVENTION { COBOL }
~~~~~~~~~~~~~~~~~ { EXTERN }
{ STDCALL }
{ STATIC }
COPY copybook-name
~~~~
[ IN|OF library-name ]
~~ ~~
[ SUPPRESS PRINTING ]
~~~~~~~~
[ REPLACING { Phrase-Clause | String-Clause }... ] .
~~~~~~~~~ { ==pseudo-text-1== } BY { ==pseudo-text-2== }
{ identifier-1 } ~~ { identifier-2 }
{ literal-1 } { literal-2 }
{ word-1 } { word-2 } [ LEADING|TRAILING ] ==partial-word-1== BY ==partial-word-2== ~~~~~~~ ~~~~~~~~ ~~
COPYstatements are used to import copybooks (see Copybooks) into a program. COPYstatements may be used anywhere within a COBOL program where the code contained within the copybook would be syntactically valid. SUPPRESS INand the wordOF— use the one you prefer. COPYstatement, even if the statement occurs within the scope of another one where a period might appear disruptive, such as within the scope of anIF(see IF) statement. This mandatory period at the end of the statement will not, however, affect the statement scope in which theCOPYoccurs. COPYstatements are located and the contents of the corresponding copybooks inserted into the program source code before the actual compilation process begins. If a copybook contains aCOPYstatement, the copybook insertion process will be repeated to resolve the embeddedCOPY This will continue until no unresolvedCOPYstatements remain. At that point, actual program compilation will begin. REPLACING Replacement of one or more complete reserved words, user-defined identifiers or literals; the following points apply to this option:
BYwill be referred to here as the search string. <identifier-1><literal-1>or<word-1>being replaced. ==<pseudo-text-1>==option. For example, to replace all occurrences ofUPON PRINTER you would specify==UPON PRINTER== BY may be specified using any of the four options. ==<pseudo-text-2>==option. If<pseudo-text-2>is null (in other words, the replacement text is specified as====, all encountered occurrences of the search string will be deleted. Using this, you may replace character sequences that occur at the beginning LEADING
REPLACE [ ALSO ] { Phrase-Clause | String-Clause }... .
~~~~~~~ ~~~~
REPLACE [ LAST ] OFF . ~~~~~~~ ~~~~ ~~~
{ ==pseudo-text-1== } BY { ==pseudo-text-2== }
~~ [ LEADING|TRAILING ] ==partial-word-1== BY ==partial-word-2== ~~~~~~~ ~~~~~~~~ ~~
REPLACEstatement provides a mechanism for changing all or part of one or more GnuCOBOL statements. REPLACEstatement (either format), even if the statement occurs within the scope of another one where a period might appear disruptive (such as within the scope of anIF(see IF) statement; the period will not, however, affect the statement scope in which theREPLACEoccurs. REPLACEstatement: REPLACEstatement can be used to make changes to program source code in much the same way as theREPLACING Replace one or more complete reserved words, user-defined identifiers or literals; the following points apply to this option:
BYwill be referred to here as the search string. REPLACEare always specified using the==<pseudo-text-1>==option. For example, to replace all occurrences ofUPON PRINTER you would specify==UPON PRINTER== BY is specified using the==<pseudo-text-2>==option. If<pseudo-text-2>is null (in other words, the replacement text is specified as====, all encountered occurrences of the search string will be deleted. Using this, you may replace character sequences that occur at the beginning LEADING
REPLACEstatement is encountered in the currently-compiling source file, Replace Mode becomes active, and the change(s) specified by that statement will be automatically made on all subsequent source statements the compiler reads from the file. REPLACEis encountered, the end of currently compiling program source file is reached or a Format 2REPLACEstatement is encountered. REPLACEstatement with theALSO REPLACEwithout theALSOkeyword is encountered, any stacked change specification(s), if any, will be discarded and the currently in-effect change specification(s), if any, will be replaced by those of the new statement. REPLACEstatement: REPLACE OFF.will deactivate Replace Mode and discard any replace specification(s) on the stack. The compiler will henceforth operate as if noREPLACEhad ever been encountered, until such time as another Format 1REPLACEis encountered. REPLACE LAST OFF.will replace the current replace specification(s) with those popped off the top of the stack. If there were no replace specification(s) on the stack, the effect will be as if aREPLACE OFF.had been coded. >>DEFINE [ CONSTANT ] cdf-variable-1 AS { OFF }
~~~~~~~~ ~~~~~~~~ { ~~~ }
{ literal-1 [ OVERRIDE ] }
{ ~~~~~~~~ }
{ PARAMETER [ OVERRIDE ] }
~~~~~~~~~ ~~~~~~~~
ASis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. END PROGRAMorEND FUNCTIONdirective is encountered in the input source. >>DEFINECDF directive is one way to create CDF variables that may be processed by other CDF statements such as>>IF(see >>IF). The>>SETCDF directive (see >>SET) provides another way to create them. CONSTANT CONSTANToption is valid only in conjunction with <literal-1>. WhenCONSTANTis specified, the CDF variable that is created may be used within your regular COBOL code as if it were a literal value. Without this option, the CDF variable may only be referenced on other CDF statements. TheOFF PARAMETER OVERRIDE >>IF CDF-Conditional-Expression-1 ~~~~ [ Program-Source-Lines-1 ] [ >>ELIF CDF-Conditional-Expression-2 ~~~~~~ [ Program-Source-Lines-2 ] ]... [ >>ELSE ~~~~~~ [ Program-Source-Lines-3 ] ] >>END-IF ~~~~~~~~
{ cdf-variable-1 } IS [ NOT ] { DEFINED }
{ literal-1 } ~~~ { ~~~~~~~ }
{ SET }
{ ~~~ }
{ CDF-RelOp { cdf-variable-2 } }
{ { literal-2 } }
>= or GREATER THAN OR EQUAL TO
~~~~~~~ ~~ ~~~~~
> or GREATER THAN
~~~~~~~
<= or LESS THAN OR EQUAL TO
~~~~ ~~ ~~~~~
< or LESS THAN
~~~~
= or EQUAL TO
~~~~~
<> or EQUAL TO (with "NOT")
~~~~~
ISTHANandTOare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. >>IFdirective must be terminated by an>>END-IF >>ELIF >>ELSE >>IF>>END-IFmay be processed by the compiler. Which one (if any) that gets processed will be decided as follows: >>ELIFclauses that may be present until one evaluates to TRUE. Once one of them evaluates to TRUE, the <<Program-Source-Lines-n>> block of code that corresponds to the TRUE <<CDF-Conditional-Expression-n>> will be one that is processed. All others within the>>IF>>END-IFscope will be ignored. >>ELSEclause, the <<Program-Source-Lines-3>> block of statements following the>>ELSEclause will be processed by the compiler and all others within the>>IF>>END-IFscope will be ignored. >>ELSEclause, then none of the <<Program-Source-Lines-n>> block of statements within the>>IF>>END-IFscope will be processed by the compiler. >>IF>>END-IFstructure. DEFINED SET IFstatement (see IF), multiple comparisons cannot be "AND"ed or "OR"ed together; you may nest a second>>IFinside the first, however, to simulate an "AND" and an "OR" may be simulated via the>>ELIFoption. <>symbol stands forNOT EQUAL TO >>SET { [ CONSTANT ] cdf-variable-1 [ AS literal-1 ] }
~~~~~ { ~~~~~~~~ ~~ }
{ SOURCEFORMAT AS FIXED|FREE }
{ ~~~~~~~~~~~~ ~~~~~ ~~~~ }
{ NOFOLDCOPYNAME }
{ ~~~~~~~~~~~~~~ }
{ FOLDCOPYNAME AS UPPER|LOWER }
~~~~~~~~~~~~ ~~~~~ ~~~~~
ASis optional (only on theSOURCEFORMATandFOLDCOPYNAMEclauses) and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. END PROGRAMorEND FUNCTIONdirective is encountered in the input source. FOLDCOPYNAME NOFOLDCOPYNAME CONSTANT >>SETCDF directive provide equivalent functionality to the>>DEFINEand>>SOURCEdirectives, as follows: >>SET <cdf-variable-1>≡>>DEFINE <cdf-variable-1> AS OFF
>>SET <cdf-variable-1> AS <literal-1>≡>>DEFINE <cdf-variable-1> AS <literal-1>
>>SET CONSTANT <cdf-variable-1> AS <literal-1>≡>>DEFINE CONSTANT <cdf-variable-1> AS <literal-1>
>>SET SOURCEFORMAT AS FIXED≡>>SOURCE FORMAT IS FIXED
>>SET SOURCEFORMAT AS FREE≡>>SOURCE FORMAT IS FREE
>>SOURCE FORMAT IS FIXED|FREE|VARIABLE ~~~~~~~~ ~~~~~ ~~~~ ~~~~~~~~
FORMATandISare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. FIXEDandFREEmode as desired. >>SETCDF directive to perform this function. >>TURN { exception-name-1 [ file-name-1 ]... }...
~~~~~~
{ OFF }
{ ~~~ }
{ CHECKING ON [ WITH LOCATION ] }
~~~~~~~~ ~~ ~~~~~~~~
>>D ~~~
>>DISPLAY source-text [ VCS = version-string ] ~~~~~~~~~ ~~~
>>PAGE ~~~~~~
>>LISTING {ON}
~~~~~~~~~ {OFF} >>LEAP-SECONDS ~~~~~~~~~~~~~~
The>>LEAP-SECONDSCDF directive is syntactically recognized but is otherwise non-functional.
$ (Dollar) Directives - Active. These directives are active and have the same function as ones starting with >>: $DISPLAY ON|OFF $SET $IF $ELIF $ELSE-IF $END $ (Dollar) Directives - Not Active. These are NOT active and will produce a warning message: $DISPLAY VCS ...
[{ IDENTIFICATION } DIVISION. ]
{ ~~~~~~~~~~~~~~ } ~~~~~~~~
{ ID }
~~
{ PROGRAM-ID. } program-id [ AS {literal-1 }] [ Type-Clause ] .
{ ~~~~~~~~~~ } {program name }]
{ FUNCTION-ID. } { literal-1 } [ AS literal-2 ].
~~~~~~~~~~~ { function-name }
{ OPTIONS. }
~~~~~~~
[ DEFAULT ROUNDED MODE IS {AWAY-FROM-ZERO }
~~~~~~~ ~~~~~~~ {NEAREST-AWAY-FROM-ZERO }
{NEAREST-EVEN }
{NEAREST-TOWARDS-ZERO }
{PROHIBITED }
{TOWARDS-GREATER }
{TOWARDS-LESSER }
{TRUNCATION }]
[ ENTRY-CONVENTION IS {COBOL }
~~~~~~~~~~~~~~~~ {EXTERN }
{STDCALL }]
[ AUTHOR. comment-1. ]
~~~~~~
[ DATE-COMPILED. comment-2. ]
~~~~~~~~~~~~~
[ DATE-MODIFIED. comment-3. ]
~~~~~~~~~~~~~
[ DATE-WRITTEN. comment-4. ]
~~~~~~~~~~~~
[ INSTALLATION. comment-5. ]
~~~~~~~~~~~~
[ REMARKS. comment-6. ]
~~~~~~~
[ SECURITY. comment-7. ]
~~~~~~~~
TheAUTHOR
IS [ COMMON ] [ INITIAL|RECURSIVE PROGRAM ]
~~~~~~ ~~~~~~~ ~~~~~~~~~
The identification division provides basic identification of the program by giving it a name and optionally defining some high-level characteristics via the eight pre-defined paragraphs that may be specified.
ASISandPROGRAMare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. PROGRAM-ID IDENTIFICATION DIVISIONorID DIVISIONheader is optional, thePROGRAM-ID/FUNCTION-ID -Wobsoleteswitch PROGRAM-IDandFUNCTION-IDparagraphs serve to identify the program to the external (i.e. operating system) environment. If there is noASclause present, the <program-id> will serve as that external identification. If there is anASclause specified, that specified literal will serve as the external identification. For the remainder of this document, that "external identification" will be referred to as the primary entry-point name. INITIALCOMMONandRECURSIVEwords are used only within subprograms serving as subroutines. Their purposes are as follows: COMMON RECURSIVE User-defined functions (i.e.FUNCTION-ID are always recursive.
INITIAL ENVIRONMENT DIVISION. ~~~~~~~~~~~ ~~~~~~~~ [ CONFIGURATION SECTION. ] ~~~~~~~~~~~~~ ~~~~~~~~ [ SOURCE-COMPUTER. Compilation-Computer-Specification . ] ~~~~~~~~~~~~~~~ [ OBJECT-COMPUTER. Execution-Computer-Specification . ] ~~~~~~~~~~~~~~~ [ SPECIAL-NAMES. Program-Configuration-Specification . ] ~~~~~~~~~~~~~ [ REPOSITORY. Function-Specification... . ] ~~~~~~~~~~ [ INPUT-OUTPUT SECTION. ] ~~~~~~~~~~~~ ~~~~~~~ [ FILE-CONTROL. General-File-Description... . ] ~~~~~~~~~~~~ [ I-O-CONTROL. File-Buffering Specification... . ] ~~~~~~~~~~~
SOURCE-COMPUTERandOBJECT-COMPUTER for example), each of which serves a specific purpose. If no code is required for the purpose one of the paragraphs serves, the entire paragraph may be omitted. ENVIRONMENT DIVISION.header itself may be omitted. CONFIGURATION SECTION. ~~~~~~~~~~~~~ ~~~~~~~ [ SOURCE-COMPUTER. Compilation-Computer-Specification . ] ~~~~~~~~~~~~~~~ [ OBJECT-COMPUTER. Execution-Computer-Specification . ] ~~~~~~~~~~~~~~~ [ SPECIAL-NAMES. Program-Configuration-Specification . ] ~~~~~~~~~~~~~ [ REPOSITORY. Function-Specification... . ] ~~~~~~~~~~
CONFIGURATION SECTION.header may be omitted from the program. SOURCE-COMPUTER. computer-name [ WITH DEBUGGING MODE ] . ~~~~~~~~~~~~~~~ ~~~~~~~~~ ~~~~
WITHis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. SOURCE-COMPUTERsettings of their parent program. OBJECT-COMPUTERparagraph, if any. DEBUGGING MODE DEBUGGING MODEclause, it is still possible to compile debugging lines. Debugging lines may also be compiled by specifying the-fdebugging-lineswitch OBJECT-COMPUTER. [ computer-name ]
~~~~~~~~~~~~~~~
[ MEMORY SIZE IS integer-1 WORDS|CHARACTERS ]
~~~~~~ ~~~~ ~~~~~ ~~~~~~~~~~
[ PROGRAM COLLATING SEQUENCE IS alphabet-name-1 ]
~~~~~~~~~
[ SEGMENT-LIMIT IS integer-2 ]
~~~~~~~~~~~~~
[ CHARACTER CLASSIFICATION IS { locale-name-1 } ]
~~~~~~~~~~~~~~ { LOCALE }
{ ~~~~~~ }
{ USER-DEFAULT }
{ ~~~~~~~~~~~~ }
{ SYSTEM-DEFAULT }
~~~~~~~~~~~~~~
. TheMEMORY SIZE
OBJECT-COMPUTERparagraph name. The remaining clauses may be coded in any sequence. CHARACTERISPROGRAMandSEQUENCEare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. SOURCE-COMPUTERparagraph, if any. OBJECT-COMPUTERparagraph is not allowed in a nested subprogram — nested programs will inherit theOBJECT-COMPUTERsettings of their parent program. COLLATING SEQUENCE COLLATING SEQUENCEclause is specified, the collating sequence implied by the character set native to the computer (usually ASCII) will be used. CLASSIFICATION The meanings of the four locale specifications are as follows:
LOCALE(see SPECIAL-NAMES) definition. LOCALErefers to the current locale (in effect at the time the program is executed) USER-DEFAULTreferences the default locale specified for the user currently executing this program. SYSTEM-DEFAULTdenotes the default locale specified for the computer upon which the program is executing. CLASSIFICATIONclause will cause character classification to occur according to the rules for the computer’s native character set (ASCII, EBCDIC, …). SPECIAL-NAMES.
~~~~~~~~~~~~~
[ CALL-CONVENTION integer-1 IS mnemonic-name-1 ]
~~~~~~~~~~~~~~~
[ CONSOLE IS CRT ]
~~~~~~~ ~~~
[ CRT STATUS IS identifier-1 ]
~~~ ~~~~~~
[ CURRENCY SIGN IS literal-1 ]
~~~~~~~~ ~~~~
[ CURSOR IS identifier-2 ]
~~~~~~
[ DECIMAL-POINT IS COMMA ]
~~~~~~~~~~~~~ ~~~~~
[ EVENT STATUS IS identifier-3 ]
~~~~~ ~~~~~~
[ LOCALE locale-name-1 IS literal-2 ]...
~~~~~~
[ NUMERIC SIGN IS TRAILING SEPARATE ]
~~~~~~~ ~~~~ ~~~~~~~~ ~~~~~~~~
[ SCREEN CONTROL IS identifier-4 ]
~~~~~~ ~~~~~~~
[ device-name-1 IS mnemonic-name-2 ]...
[ feature-name-1 IS mnemonic-name-3 ]...
[ Alphabet-Clause ]...
[ Class-Definition-Clause ]...
[ Switch-Definition-Clause ]...
[ Symbolic-Characters-Clause ]...
.
TheEVENT STATUS
TheSPECIAL-NAMESparagraph provides a means for specifying various program and operating environment configuration options.
SPECIAL-NAMESparagraph may be coded in any order. ISis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. SPECIAL-NAMESparagraph is not allowed in a nested subprogram — nested programs will inherit theSPECIAL-NAMESsettings of their parent program. CALL-CONVENTION CONSOLE IS CRT CRT STATUS CURRENCY SIGN CURSOR IS DECIMAL POINT IS COMMA LOCALE af_ZA, am_ET, ar_AE, ar_BH, ar_DZ, ar_EG, ar_IQ, ar_JO, ar_KW, ar_LB, ar_LY, ar_MA, ar_OM, ar_QA, ar_SA, ar_SY, ar_TN, ar_YE, arn_CL, as_IN, az_Cyrl_AZ, az_Latn_AZ
ba_R, be_BY, bg_BG, bn_IN bo_BT, bo_CN, br_FR, bs_Cyrl_BA, bs_Latn_BA
ca_ES, cs_CZ, cy_GB
da_DK, de_AT, de_CH, de_DE, de_LI, de_LU, dsb_DE, dv_MV
el_GR, en_029, en_AU, en_BZ, en_CA, en_GB, en_IE, en_IN, en_JM, en_MY en_NZ, en_PH, en_SG, en_TT, en_US, en_ZA, en_ZW, es_AR, es_BO, es_CL, es_CO, es_CR, es_DO, es_EC, es_ES, es_GT, es_HN, es_MX, es_NI, es_PA, es_PE, es_PR, es_PY, es_SV, es_US, es_UY es_VE, et_EE, eu_ES
fa_IR, fi_FI, fil_PH, fo_FO, fr_BE, fr_CA, fr_CH, fr_FR, fr_LU, fr_MC, fy_NL
ga_IE, gbz_AF, gl_ES, gsw_FR, gu_IN
ha_Latn_NG, he_IL, hi_IN, hr_BA, hr_HR, hu_HU, hy_AM
id_ID, ig_NG, ii_CN, is_IS, it_CH, it_IT, iu_Cans_CA, iu_Latn_CA
ja_JP
ka_GE, kh_KH, kk_KZ, kl_GL, kn_IN, ko_KR, kok_IN, ky_KG
lb_LU, lo_LA, lt_LT, lv_LV
mi_NZ, mk_MK, ml_IN, mn_Cyrl_MN, mn_Mong_CN moh_CA, mr_IN, ms_BN, ms_MY, mt_MT
nb_NO, ne_NP, nl_BE, nl_NL, nn_NO, ns_ZA
oc_FR, or_IN
pa_IN, pl_PL, ps_AF, pt_BR, pt_PT
qut_GT, quz_BO, quz_EC, quz_PE
rm_CH, ro_RO, ru_RU, rw_RW
sa_IN, sah_RU, se_FI, se_NO se_SE, si_LK, sk_SK, sl_SI, sma_NO, sma_SE, smj_NO, smj_SE, smn_FI, sms_FI, sq_AL, sr_Cyrl_BA, sr_Cyrl_CS, sr_Latn_BA, sr_Latn_CS, sv_FI, sv_SE, sw_KE syr_SY
ta_IN, te_IN, tg_Cyrl_TJ, th_TH tk_TM, tmz_Latn_DZ, tn_ZA, tr_IN, tr_TR, tt_RU
ug_CN, uk_UA, ur_PK, uz_Cyrl_UZ, uz_Latn_UZ
vi_VN
wen_DE, wo_SN
xh_ZA
yo_NG
zh_CN, zh_HK, zh_MO, zh_SG, zh_TW, zu_ZA
NUMERIC SIGN TRAILING SEPARATE <device-name-1> IS <mnemonic-name-2>clause allows you to specify an alternate name (<device-name-1>) for one of the built-in GnuCOBOL device name <mnemonic-name-2>. The list of device names built-into GnuCOBOL, and the physical device associated with that name, are as follows: CONSOLE This is the (screen-mode) display of the PC or Unix system.
STDIN SYSIN SYSIPT These devices (they are all synonymous) represent standard system input (pipe 0). On a PC or UNIX system, this is typically the keyboard. The contents of a file may be delivered to a GnuCOBOL program for access via one of these device names by adding the sequence "0< filename" to the end of the programs execution command.
PRINTER STDOUT SYSLIST SYSLST SYSOUT These devices (they are all synonymous) represent standard system output (pipe 1). On a PC or UNIX system, this is typically the display. Output sent to one of these devices by a GnuCOBOL program can be sent to a file by adding the sequence "1> filename" to the end of the programs execution command.
STDERR SYSERR These devices (they are synonymous) represent standard system error output (pipe 2). On a PC or UNIX system, this is typically the display. Output sent to one of these devices by a GnuCOBOL program can be sent to a file by adding the sequence "2> filename" to the end of the programs execution command.
<feature-name-1> IS <mnemonic-name-3>clause allow for mnemonic names to be assigned to up to the 13 printer channel (i.e. vertical page positioning) position feature namesCnn(nn=01-12) andCSP Once a channel position has been assigned a mnemonic name, statements of the formWRITE <record-name> AFTER ADVANCING <mnemonic-name-3>may be coded to write the specified print record at the channel position assigned to <mnemonic-name-3>. Printers supporting channel positioning are generally mainframe-type line printers. When writing to printers that do not support channel positioning, a formfeed will be issued to the printer.
TheCSPpositioning option stands for "No Spacing". Testing on a MinGW build of GnuCOBOL shows that this too results in a formfeed being issued.
ALPHABET alphabet-name-1 IS { ASCII }
~~~~~~~~ { ~~~~~ }
{ EBCDIC }
{ ~~~~~~ }
{ NATIVE }
{ ~~~~~~ }
{ STANDARD-1 }
{ ~~~~~~~~~~ }
{ STANDARD-2 }
{ ~~~~~~~~~~ }
{ Literal-Clause... }
literal-1 [ { THRU|THROUGH literal-2 } ]
{ ~~~~ ~~~~~~~ }
{ {ALSO literal-3}... }
~~~~
ISis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. THRUandTHROUGHare interchangeable. ASCII NATIVE NATIVEcharacter set, either by it’s actual text value (alphanumeric quoted character) or by ordinal position in theNATIVEcharacter set (integer), NATIVEcharacter set. SPACESPACESZEROZEROSZEROESQUOTEQUOTESHIGH-VALUEHIGH-VALUESLOW-VALUEorLOW-VALUESfor any of the <literal-1>, <literal-2> or <literal-3> specifications. CODE-SETCOLLATING SEQUENCE orSYMBOLIC CHARACTERSclauses elsewhere in the program. CLASS class-name-1 IS { literal-1 [ THRU|THROUGH literal-2 ] }...
~~~~~ ~~~~ ~~~~~~~
ISis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. THRUandTHROUGHare interchangeable.
CLASS Hexadecimal IS '0' THRU '9'
'A' THRU 'F'
'a' THRU 'f'
IF input-item IS Hexadecimalto determine if the value of characters in a data item are valid according to that class. switch-name-1 [ IS mnemonic-name-1 ]
[ ON STATUS IS condition-name-1 ]
~~
[ OFF STATUS IS condition-name-2 ]
~~~
ISandSTATUSare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. SWITCH-n -fsyntax-extensionswitch IS <mnemonic-name-1>ON STATUSor anOFF STATUSoption defined for it, otherwise there will be no way to reference the switch from within a GnuCOBOL program. IS <mnemonic-name-1>syntax provides a means for setting the switch to either an ON or OFF value via theSETstatement (see SET). ON STATUS SYMBOLIC CHARACTERS
~~~~~~~~
{ symbolic-character-1... IS|ARE integer-1... }...
[ IN alphabet-name-1 ]
~~
ARECHARACTERSandISare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. INclause. The integer values are selecting characters from the alphabet by their ordinal position and not by their numeric value; thus, an integer of 15 will select the 15th character in the specified alphabet, regardless of the actual numeric value of the bit pattern that constitutes that character. SYMBOLIC CHARACTERS NUL IS 1 SYMBOLIC CHARACTERS NUL SOH BEL DC1 DC2SOH IS 2 ARE 1 2 8 18 19BEL IS 8DC1 IS 18DC2 IS 19
REPOSITORY.
~~~~~~~~~~
FUNCTION { function-prototype-name-1 [ AS literal-1 ] }...
~~~~~~~~ { ~~ }
{ intrinsic-function-name-1 [ AS literal-2 ] }
{ ~~ }
{ intrinsic-function-name-2 INTRINSIC }
{ ALL INTRINSIC ~~~~~~~~~ }
~~~ ~~~~~~~~~
REPOSITORYparagraph is not allowed in a nested subprogram — nested programs will inherit theREPOSITORYsettings of their parent program. INTRINSIC ALL INTRINSIC ASclause to provide an alias name for a built-in intrinsic function. FUNCTIONkeyword, (2) names two user-defined functions named "MY-FUNCTION-1" and "MY-FUNCTION-2" that will be used by the program and (3) specifies the alias names "SIGMA" for the intrinsic function "STANDARD-DEVIATION" and "MF2" for "MY-FUNCTION-2".
REPOSITORY.
FUNCTION ALL INTRINSIC.
FUNCTION MY-FUNCTION-1.
FUNCTION MY-FUNCTION-2 AS "MF2".
FUNCTION STANDARD-DEVIATION AS "SIGMA".
A special note about user-defined functions — because you must name a user-defined function that your program will be using in theREPOSITORYparagraph, you may always reference that function from your program’s procedure division without needing to use theFUNCTIONkeyword.
[ INPUT-OUTPUT SECTION. ]
~~~~~~~~~~~~ ~~~~~~~
[ FILE-CONTROL. ]
~~~~~~~~~~~~
[ SELECT-Statement... ]
[ I-O-CONTROL. ]
~~~~~~~~~~~
[ MULTIPLE-FILE-Statement ]
[ SAME-RECORD-Statement ]
INPUT-OUTPUT SECTION.header itself may be omitted, otherwise it is normally required. FILE-CONTROLandI-O-CONTROLparagraphs may be specified without theINPUT-OUTPUT SECTION.header having been coded. I-O-CONTROLparagraph, the order in which those statements are coded is irrelevant. SELECT [ [ NOT ] OPTIONAL ] file-name-1
~~~~~~ ~~~ ~~~~~~~~
[ ASSIGN { TO } [{ EXTERNAL }] [{ DISC|DISK }] [{ identifier-1 }] ]
~~~~~~ { USING } { ~~~~~~~~ } { ~~~~ ~~~~ } { word-1 }
{ DYNAMIC } { DISPLAY } { literal-1 }
~~~~~~~ { ~~~~~~~ }
{ KEYBOARD }
{ ~~~~~~~~ }
{ LINE ADVANCING }
{ ~~~~ ~~~~~~~~~ }
{ PRINTER }
{ ~~~~~~~ }
{ RANDOM }
{ ~~~~~~ }
{ TAPE }
~~~~
[ COLLATING SEQUENCE IS alphabet-name-1 ]
~~~~~~~~~
[ FILE|SORT ] STATUS IS identifier-2 [ identifier-3 ] ]
~~~~ ~~~~ ~~~~~~
[ LOCK MODE IS { MANUAL|AUTOMATIC } ]
~~~~ { ~~~~~~ ~~~~~~~~~ }
{ EXCLUSIVE [ WITH { LOCK ON MULTIPLE RECORDS } ] }
~~~~~~~~~ { ~~~~ ~~ ~~~~~~~~ ~~~~~~~ }
{ LOCK ON RECORD }
[ ORGANIZATION-Clause ] { ~~~~ ~~ ~~~~~~ }
{ ROLLBACK }
[ RECORD DELIMITER IS STANDARD-1 ] ~~~~~~~~
~~~~~~ ~~~~~~~~~ ~~~~~~~~~~
[ RESERVE integer-1 AREAS ]
~~~~~~~
[ SHARING WITH { ALL OTHER } ]
~~~~~~~ { ~~~ }
{ NO OTHER }
{ ~~ }
{ READ ONLY }
~~~~ ~~~~
TheCOLLATING SEQUENCE
TheSELECTstatement creates a definition of a file and links that COBOL definition to the external operating system environment.
AREASISMODEOTHERSEQUENCETOUSINGandWITHare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. OPTIONAL ASSIGNclause specifies how — at runtime, when <file-name-1> is opened — either a logical device (STDIN, STDOUT) or a file anywhere in one of the currently-mounted file systems will be associated with <file-name-1>, as follows: ASSIGNclause — a <<Type>> specification EXTERNALDYNAMICor neither), a <<Device>> (the list of device choices) and a <<Locator>> (shown as a choice between <identifier-1>, <word-1> and <literal-1>). ASSIGN TO DISC '<file-name-1>'will be assumed if there is noASSIGNclause on aSELECT ASSIGNclause is coded without a <<Device>>, the deviceDISCwill be assumed. EXTERNALis specified, <word-1> itself will serve as the File Location String that will identify the data file. If, however, a <<Type>> ofEXTERNALwas not specified, the compiler will create aPIC X(1024)data item named <word-1> within the program; the contents of that data item at the time the program opens <file-name-1> will then serve as the File Location String that will identify the data file. DISCorDISKwill assume an attachment to a file named <file-name-1> in whatever directory is current at the time the file is opened. DISPLAYwill assume an attachment to theSTDOUTlogical device; these files should only be used for output. KEYBOARDwill assume an attachment to theSTDINlogical device; these files should only be used for input. PRINTERwill assume an attachment to theLPT1logical device/port; these files should only be used for output. RANDOMorTAPEwill behave exactly asDISCdoes. These two additional <<Device>>s are provided to facilitate the compilation of COBOL source from other COBOL implementations. LINE ADVANCINGdevice requires that a <<Locator>> be specified; these files should only be used for output. A COBOL Line Advancing file will allow carriage-control characters such as line-feeds and form-feeds to be written to the attached operating system file, via theADVANCINGclause of theWRITEstatement (see WRITE). DD_bbbb dd_bbbb bbbb
Windows systems are case-insensitive with regard to environment variables, so there is no difference between the first two when using a GnuCOBOL implementation built for either Windows/MinGW or native Windows.
If an environment variable was found, it’s value will serve as the path and filename to the data file.
C:\Data\datafile.dat/Data/datafile.dat …) or relative-to-the-current-directory Data\datafile.datData/datafile.dat …) basis. There may not even be a path datafile.dat, in which case the file must be in the current directory.
FILE STATUS | Code | Explanation |
|---|---|
| 00 | Success |
| 02 | Success (Duplicate Record Key Written) |
| 05 | Success (Optional File Not Found) |
| 07 | Success (No Unit) |
| 10 | End of file reached if reading forward or beginning-of-file reached if reading backward |
| 14 | Out of key range |
| 21 | Key invalid |
| 22 | Attempt to duplicate key value |
| 23 | Key not found |
| 30 | Permanent I/O error |
| 31 | Inconsistent filename |
| 34 | Boundary violation |
| 35 | File not found |
| 37 | Permission denied |
| 38 | Closed with lock |
| 39 | Conflicting attribute |
| 41 | File already open |
| 42 | File not open |
| 43 | Read not done |
| 44 | Record overflow |
| 46 | Read error |
| 47 |
OPEN INPUTdenied (insufficient permissions to read file) |
| 48 |
OPEN OUTPUTdenied (insufficient permissions to write to file) |
| 49 |
OPEN I-Odenied (insufficient permissions to read and/or write file) |
| 51 | Record locked |
| 52 | End of page |
| 57 |
LINAGEspecifications invalid |
| 61 | File sharing failure |
| 91 | File not available |
SHARING LOCK SELECTstatement without anORGANIZATIONexplicitly coded will be handled as if the following ORGANIZATION clause had been specified: ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
[ ORGANIZATION|ORGANISATION IS ] RECORD BINARY SEQUENTIAL
~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~
[ ACCESS MODE IS SEQUENTIAL ]
~~~~~~ ~~~~~~~~~~
BINARYISMODEandRECORDare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. ORGANIZATIONandORGANISATIONare interchangeable. ORGANIZATION IS(and it’s internationalized alternative,ORGANISATION IS is optional to provide compatibility with those (few) COBOL implementations that considerORGANIZATIONto be optional. Most COBOL implementations do require the wordORGANIZATION so it should be used in new programs. ORGANIZATION IS LINE SEQUENTIALinstead). USAGE DISPLAYorUSAGE COMPUTATIONAL(of any variety) data since no binary data sequence can be accidentally interpreted as an end-of-record delimiter. ORGANIZATION SEQUENTIALfile may be defined as having variable-length records, the file will be structured in such a manner as to reserve space for each record equal to the size of the largest possible record, based on the file’s description in theFILE SECTION ACCESS MODE SEQUENTIAL [ ORGANIZATION|ORGANISATION IS ] LINE SEQUENTIAL
~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~ ~~~~~~~~~~
[ ACCESS MODE IS SEQUENTIAL ]
~~~~~~ ~~~~~~~~~~
[ PADDING CHARACTER IS literal-1 | identifier-1 ]
~~~~~~~
ThePADDING CHARACTERclause is syntactically recognized but is otherwise non-functional.
CHARACTERISandMODEare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. ORGANIZATIONandORGANISATIONare interchangeable. ORGANIZATION IS(and it’s internationalized alternative,ORGANISATION IS is optional to provide compatibility with those (few) COBOL implementations that consider that word to be optional. Most COBOL implementations do require the wordORGANIZATION so it should be used in new programs. ORGANIZATIONvalid for files that are assigned to thePRINTERdevice. USAGE COMPUTATIONALorBINARY(of any variety) data since such fields could accidentally contain byte sequences that could be interpreted as an end-of-record delimiter. LINE SEQUENTIALfile, records in excess of the size implied by the file’s description in theFILE SECTIONwill be truncated while records shorter than that size will be padded to the right withSPACES ACCESS MODE SEQUENTIAL PRINTERorCONSOLEshould be specified asORGANIZATION LINE SEQUENTIAL [ ORGANIZATION|ORGANISATION IS ] RELATIVE
~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~
[ ACCESS MODE IS { SEQUENTIAL } ]
~~~~~~ { ~~~~~~~~~~ }
{ DYNAMIC }
{ ~~~~~~~ }
{ RANDOM }
~~~~~~
[ RELATIVE KEY IS identifier-1 ]
~~~~~~~~
ISKEYandMODEare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. ORGANIZATIONandORGANISATIONare interchangeable. ORGANIZATION IS(and it’s internationalized alternative,ORGANISATION IS is optional to provide compatibility with those (few) COBOL implementations that consider that word to be optional. Most COBOL implementations do require the wordORGANIZATION so it should be used in new programs. ORGANIZATION RELATIVEfiles cannot be assigned to theCONSOLEDISPLAYLINE ADVANCINGorPRINTERdevices. RELATIVE KEY ORGANIZATION RELATIVEfile may be defined as having variable-length records, the file will be structured in such a manner as to reserve space for each record equal to the size of the largest possible record as defined by the file’s description in theFILE SECTION ACCESS MODE SEQUENTIAL the defaultACCESS MODEif none is specified, indicates that the records of the file will be processed in a sequential manner, according to their physical sequence in the file. ACCESS MODE RANDOM ACCESS MODE DYNAMIC RELATIVE KEY [ ORGANIZATION|ORGANISATION IS ] INDEXED
~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~
[ ACCESS MODE IS { SEQUENTIAL } ]
~~~~~~ { ~~~~~~~~~ }
{ DYNAMIC }
{ ~~~~~~~ }
{ RANDOM }
~~~~~~
[ RECORD KEY IS identifier-1
~~~~~~
[ =|{SOURCE IS} identifier-2 ] ]
~~~~~~
[ ALTERNATE RECORD KEY IS identifier-3
~~~~~~~~~ ~~~~~~
[ =|{SOURCE IS} identifier-4 ]
~~~~~~
[ WITH DUPLICATES ] ]...
~~~~~~~~~~
TheSOURCEclause is syntactically recognized but is otherwise non-functional. It is supported to provide compatibility with COBOL source written for other COBOL implementations.
ISKEYandMODEare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. ORGANIZATIONandORGANISATIONare interchangeable. ORGANIZATION IS(and it’s internationalized alternative,ORGANISATION IS is optional to provide compatibility with those (few) COBOL implementations that consider that word to be optional. Most COBOL implementations do require the wordORGANIZATION so it should be used in new programs. ORGANIZATION INDEXEDfiles cannot be assigned toCONSOLEDISPLAYKEYBOARDLINE ADVANCINGorPRINTER ACCESS MODE SEQUENTIAL ACCESS MODE RANDOM ACCESS MODE DYNAMIC PRIMARY KEY ALTERNATE RECORD KEY ALTERNATE RECORD KEYclauses, each defining an additional alternate key for the file. SAME { SORT-MERGE } AREA FOR file-name-1... .
~~~~ { ~~~~~~~~~~ }
{ SORT }
{ ~~~~ }
{ RECORD }
~~~~~~
TheSAME SORT-MERGE
AREAandFORare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. MULTIPLE FILE TAPE CONTAINS
~~~~~~~~
{ file-name-1 [ POSITION integer-1 ] }...
~~~~~~~~
.
TheMULTIPLE FILE TAPEclause is obsolete and is therefore recognized but not functional.
DATA DIVISION.
~~~~ ~~~~~~~~
[ FILE SECTION.
~~~~ ~~~~~~~
{ File/Sort-Description [ { FILE-SECTION-Data-Item } ]... }... ]
{ { 01-Level-Constant } }
{ { 78-Level-Constant } }
{ 01-Level-Constant }
{ 78-Level-Constant }
[ WORKING-STORAGE SECTION.
~~~~~~~~~~~~~~~ ~~~~~~~
[ { WORKING-STORAGE-SECTION-Data-Item } ]... ]
{ 01-Level-Constant }
{ 78-Level-Constant }
[ LOCAL-STORAGE SECTION.
~~~~~~~~~~~~~ ~~~~~~~
[ { LOCAL-STORAGE-SECTION-Data-Item } ]... ]
{ 01-Level-Constant }
{ 78-Level-Constant }
[ LINKAGE SECTION.
~~~~~~~ ~~~~~~~
[ { LINKAGE-SECTION-Data-Item } ]... ]
{ 01-Level-Constant }
{ 78-Level-Constant }
[ REPORT SECTION.
~~~~~~ ~~~~~~~
{ Report-Description [ { Report-Group-Definition } ]... }... ]
{ { 01-Level-Constant } }
{ { 78-Level-Constant } }
{ 01-Level-Constant }
{ 78-Level-Constant }
[ SCREEN SECTION.
~~~~~~ ~~~~~~~
[ { SCREEN-SECTION-Data-Item } ]... ]
{ 01-Level-Constant }
{ 78-Level-Constant }
DATA DIVISION.header itself may be omitted. TheEmployeedata item consists of two subordinate data items — anEmployee-Nameand anEmployment-Datesdata item (presumably there would be a lot of others too, but we don’t care about them right now). As the diagram shows, each of those data items are, in turn, broken down into subordinate data items. This hierarchy of data items can get ratherdeep and GnuCOBOL, like other COBOL implementations, can handle up to 49 levels of such hierarchical structures.
As was presented earlier (see Structured Data), a data item that is broken down into other data items is referred to as a group item, while one that isn’t broken down is called an elementary item.
COBOL uses the concept of a "level number" to indicate the level at which a data item occurs in a data structure such as the example shown above. When these data items are defined, they are all defined together with a number in the range 1-49 specified in front of their names. Over the years, a convention has come to exist among COBOL programmers that level numbers are always coded as two-digit numbers — they don’t have to be specified as two-digit numbers, but every example you see in this document will take that approach!
The data item at the top, also referred to as a "record", always has a level number of 01. After that, you may assign level numbers as you wish (01–02–03–04…, 01–05–10–15…, etc.), as long as you follow these simple rules:
levelof a hierarchy diagram such as the one you see here (if you were to make one, which you rarely — if ever — will, once you get used to this concept) must have the same level number. So, the definition of these data items in a GnuCOBOL program would go something like this:
01 Employee
05 Employee-Name
10 Last-Name
10 First-Name
10 Middle-Initial
05 Employment-Dates
10 From-Date
15 Year
15 Month
15 Day
10 To-Date
15 Year
15 Month
15 Day
The indentation is purely at the discretion of the programmer to make things easier for humans to read (the compiler couldn’t care less). Historically, COBOL implementations that required Fixed Format Mode source programs required that the01level number begin in Area A and that everything else begins in Area B. GnuCOBOL only requires that all data definition syntax occur in columns 8-72. In Free Format Mode, of course, there aren’t even those limitations.
Did you notice that there are two each ofYearMonthandDaydata names defined? That’s perfectly legal, provided that each can be uniquelyqualifiedso as to be distinct from the other. Take for example theYearitems. One is defined as part of theFrom-Datedata item while the other is defined as part of the "To-Date" data item. In COBOL, we would actually code references to these two data items as eitherYear OF From-DateandYear OF To-DateorYear IN From-DateandYear IN To-Date(COBOL allows eitherINorOFto be used). Since these references would clarify any confusion to us as to whichYearmight be referenced, the GnuCOBOL compiler won’t be confused either.
The coding example shown above is incomplete — it only describes the data item names and their hierarchical relationships to one other. In addition, any valid data item definitions will also need to describe what type of data is to be contained in a data item (Numeric? Alphanumeric? Alphabetic?), how much data can be held in the data item and a multitude of other characteristics.
When group items are being defined, subordinate items may be assigned anameofFILLER
[ FILE SECTION.
~~~~ ~~~~~~~
{ File/Sort-Description [ { FILE-SECTION-Data-Item } ]... }... ]
{ { 01-Level-Constant } }
{ { 78-Level-Constant } }
{ 01-Level-Constant }
{ 78-Level-Constant }
Files destined for use as sort/merge work files must be described with a Sort/Merge File Description SD while every other file is described with a File Description FD. Each of these descriptions will almost always be followed with at least one record description.
FD|SD file-name-1 [ IS EXTERNAL|GLOBAL ]
~~ ~~ ~~~~~~~~ ~~~~~~
[ BLOCK CONTAINS [ integer-1 TO ] integer-2 CHARACTERS|RECORDS ]
~~~~~ ~~ ~~~~~~~~~~ ~~~~~~~
[ CODE-SET IS alphabet-name-1 ]
~~~~~~~~
[ DATA { RECORD IS } identifier-1... ]
~~~~ { ~~~~~~ }
{ RECORDS ARE }
~~~~~~~
[ LABEL { RECORD IS } OMITTED|STANDARD ]
~~~~~ { ~~~~~~ } ~~~~~~~ ~~~~~~~~
{ RECORDS ARE }
~~~~~~~
[ LINAGE IS integer-3 | identifier-2 LINES
~~~~~~
[ LINES AT BOTTOM integer-4 | identifier-3 ]
~~~~~~
[ LINES AT TOP integer-5 | identifier-4 ]
~~~
[ WITH FOOTING AT integer-6 | identifier-5 ] ]
~~~~~~~
[ RECORD { CONTAINS [ integer-7 TO ] integer-8 CHARACTERS } ]
~~~~~~ { ~~ }
{ IS VARYING IN SIZE }
{ ~~~~~~~ }
{ [ FROM [ integer-7 TO ] integer-8 CHARACTERS }
{ ~~ }
{ DEPENDING ON identifier-6 ] }
~~~~~~~~~
[ RECORDING MODE IS recording-mode ]
~~~~~~~~~
[ { REPORT IS } report-name-1... ]
{ ~~~~~~ }
{ REPORTS ARE }
~~~~~~~
[ VALUE OF implementor-name-1 IS literal-1 | identifier-7 ] .
~~~~~ ~~ TheBLOCK CONTAINS
AREATCHARACTERSRECORDclause only),CONTAINSFROMINISONandWITHare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. RECORD ISandRECORDS AREare interchangeable. REPORT ISandREPORTS AREare interchangeable. SORT(see SORT) orMERGE(see MERGE) statements should be coded with an SD — all others should be defined with a FD. FDorSD as compared to the sequence in which theirSELECTstatements were coded, is irrelevant. SELECTstatement. CODE-SET LINAGEclause may only be specified in theFDof a sequential or line sequential file. If used with a sequential file, the organization of that file will be implicitly changed to line sequential. The various components of theLINAGEclause define the layout of printed pages as follows: LINES AT TOP LINES AT BOTTOM LINAGE IS n LINES FOOTING AT WRITEstatement (see WRITE). LINAGEclause in anFDwill cause theLINAGE-COUNTERspecial register to be created for the file. This automatically-created data item will always contain the current relative line number on the page being prepared which will serve as the starting point for aWRITEstatement. RECORD CONTAINS REPORT IS FDof a sequential or line sequential file. If used with a sequential file, the organization of that file will be implicitly changed to line sequential. FDcannot be followed by record descriptions — detailed descriptions of data to be printed to the file will be defined in theREPORT SECTION(see REPORT SECTION). LINAGEclause is also specified, Values specified forLINAGE ISandFOOTING ATwill be ignored. The values ofLINES AT BOTTOMandLINES AT TOP if any, will be honoured. DISK(orDISC on theirSELECTstatements. (in that order)
SORTorMERGEtermination. They will also be purged if the program terminates abnormally before theSORTorMERGEfinishes. Should you ever need to know, temporary sort/merge work files will be named "cob*.tmp". SELECT it will be ignored. EXTERNALandGLOBALoptions. level-number [ identifier-1 | FILLER ] [ IS GLOBAL|EXTERNAL ]
~~~~~~ ~~~~~~ ~~~~~~~~
[ BLANK WHEN ZERO ]
~~~~~ ~~~~
[ JUSTIFIED RIGHT ]
~~~~
[ OCCURS [ integer-1 TO ] integer-2 TIMES
~~~~~~ ~~
[ DEPENDING ON identifier-2 ]
~~~~~~~~~
[ ASCENDING|DESCENDING KEY IS identifier-3 ]
~~~~~~~~~ ~~~~~~~~~~
[ INDEXED BY identifier-4 ] ]
~~~~~~~
[ PICTURE IS picture-string ]
~~~
[ REDEFINES identifier-5 ]
~~~~~~~~~
[ SIGN IS LEADING|TRAILING [ SEPARATE [CHARACTER] ] ]
~~~~ ~~~~~~~ ~~~~~~~~ ~~~~~~~~
[ SYNCRONIZED|SYNCHRONISED [ LEFT|RIGHT ] ]
~~~~ ~~~~ ~~~~ ~~~~~
[ USAGE IS data-item-usage ] . [ FILE-SECTION-Data-Item ]...
~~~~~ TheLEFTandRIGHT(SYNCRONIZED) clauses are syntactically recognized but are otherwise non-functional.
BYISKEYONandWHENare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. SYNCRONIZEDandSYNCRONIZEDare interchangeable. Both may be abbreviated toSYNC PICTUREmay be abbreviated toPIC FDorSDis found — this marks the completion of the detailed description of the file and begins another. FDorSD the one with the longest length will define the size of the record buffer into which aREADstatement (see READ) or aRETURNstatement (see RETURN) will deliver data read from the file and from which aWRITEstatement (see WRITE) orRELEASEstatement (see RELEASE) statement will obtain the data to be written to the file. SAME RECORD AREA(see SAME RECORD AREA) clause. FILLERimmediately after the level number has the same effect as ifFILLERwere specified. A data item namedFILLERcannot be referenced directly; these items are generally used to specify an unused portion of the total storage allocated to a group item or to describe a group item whose contents which will only be referenced using the names of those items that belong to it. EXTERNALcannot be combined withGLOBALorREDEFINES level-number [ identifier-1 | FILLER ] [ IS GLOBAL | EXTERNAL ]
~~~~~~ ~~~~~~ ~~~~~~~~
[ BASED ]
~~~~~
[ BLANK WHEN ZERO ]
~~~~~ ~~~~
[ JUSTIFIED RIGHT ]
~~~~
[ OCCURS [ integer-1 TO ] integer-2 TIMES
~~~~~~ ~~
[ DEPENDING ON identifier-2 ]
~~~~~~~~~
[ ASCENDING|DESCENDING KEY IS identifier-3 ]
~~~~~~~~~ ~~~~~~~~~~
[ INDEXED BY identifier-4 ] ]
~~~~~~~
[ PICTURE IS picture-string ]
~~~
[ REDEFINES identifier-5 ]
~~~~~~~~~
[ SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ]
~~~~ ~~~~~~~ ~~~~~~~~ ~~~~~~~~
[ SYNCRONIZED|SYNCHRONISED [ LEFT|RIGHT ] ]
~~~~ ~~~~ ~~~~ ~~~~~
[ USAGE IS data-item-usage ]
~~~~~
[ VALUE IS [ ALL ] literal-1 ] . [ WORKING-STORAGE-SECTION-Data-Item ]...
~~~~~ ~~~ TheLEFTandRIGHT(SYNCRONIZED) clauses are syntactically recognized but are otherwise non-functional.
BYCHARACTERISKEYONRIGHT(JUSTIFIED),TIMESandWHENare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. SYNCRONIZEDandSYNCHRONISEDare interchangeable. Both may be abbreviated asSYNC PICTUREmay be abbreviated toPIC JUSTIFIEDmay be abbreviated toJUST FILLERimmediately after the level number has the same effect as ifFILLERwere specified. A data item namedFILLERcannot be referenced directly; these items are generally used to specify an unused portion of the total storage allocated to a group item or to describe a group item whose contents which will only be referenced using the names of those items that belong to it. CANCELstatement (see CANCEL)), in which case initialization will happen each time they are loaded. See Data Initialization, for a discussion of the initialization rules. level-number [ identifier-1 | FILLER ] [ IS GLOBAL|EXTERNAL ]
~~~~~~ ~~~~~~ ~~~~~~~~
[ BASED ]
~~~~~
[ BLANK WHEN ZERO ]
~~~~~ ~~~~
[ JUSTIFIED RIGHT ]
~~~~
[ OCCURS [ integer-1 TO ] integer-2 TIMES
~~~~~~ ~~
[ DEPENDING ON identifier-2 ]
~~~~~~~~~
[ ASCENDING|DESCENDING KEY IS identifier-3 ]
~~~~~~~~~ ~~~~~~~~~~
[ INDEXED BY identifier-4 ] ]
~~~~~~~
[ PICTURE IS picture-string ]
~~~
[ REDEFINES identifier-5 ]
~~~~~~~~~
[ SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ]
~~~~ ~~~~~~~ ~~~~~~~~ ~~~~~~~~
[ SYNCRONIZED|SYNCHRONISED [ LEFT|RIGHT ] ]
~~~~ ~~~~ ~~~~ ~~~~~
[ USAGE IS data-item-usage ]
~~~~~
[ VALUE IS [ ALL ] literal-1 ] . [ LOCAL-STORAGE-SECTION-Data-Item ]...
~~~~~ ~~~ TheLEFTandRIGHT(SYNCRONIZED) clauses are syntactically recognized but are otherwise non-functional.
BYCHARACTERISKEYONRIGHT(JUSTIFIED),TIMESandWHENare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. SYNCRONIZEDandSYNCHRONISEDare interchangeable. Both may be abbreviated asSYNC PICTUREmay be abbreviated toPIC JUSTIFIEDmay be abbreviated toJUST FILLERimmediately after the level number has the same effect as ifFILLERwere specified. A data item namedFILLERcannot be referenced directly; these items are generally used to specify an unused portion of the total storage allocated to a group item or to describe a group item whose contents which will only be referenced using the names of those items that belong to it. level-number [ identifier-1 | FILLER ] [ IS GLOBAL|EXTERNAL ]
~~~~~~ ~~~~~~ ~~~~~~~~
[ ANY LENGTH ]
~~~ ~~~~~~
[ BASED ]
~~~~~
[ BLANK WHEN ZERO ]
~~~~~ ~~~~
[ JUSTIFIED RIGHT ]
~~~~
[ OCCURS [ integer-1 TO ] integer-2 TIMES
~~~~~~ ~~
[ DEPENDING ON identifier-3 ]
~~~~~~~~~
[ ASCENDING|DESCENDING KEY IS identifier-4 ]
~~~~~~~~~ ~~~~~~~~~~
[ INDEXED BY identifier-5 ] ]
~~~~~~~
[ PICTURE IS picture-string ]
~~~
[ REDEFINES identifier-6 ]
~~~~~~~~~
[ SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ]
~~~~ ~~~~~~~ ~~~~~~~~ ~~~~~~~~
[ SYNCRONIZED|SYNCHRONISED [ LEFT|RIGHT ] ]
~~~~ ~~~~ ~~~~ ~~~~~
[ USAGE IS data-item-usage ] . [ LINKAGE-SECTION-Data-Item ]...
~~~~~ TheLEFTandRIGHT(SYNCRONIZED) clauses are syntactically recognized but are otherwise non-functional.
BYCHARACTERISKEYONandWHENare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. SYNCRONIZEDand "SYNCHRONISED" are interchangeable. Both may be abbreviated asSYNC PICTUREmay be abbreviated toPIC JUSTIFIEDmay be abbreviated toJUST PROCEDURE DIVISION USING(see PROCEDURE DIVISION USING) or as arguments on anENTRYstatement. CALLstatement (see CALL) or an argument on a function call to the subprogram. FILLERimmediately after the level number has the same effect as ifFILLERwere specified. A data item namedFILLERcannot be referenced directly; these items are generally used to specify an unused portion of the total storage allocated to a group item or to describe a group item whose contents which will only be referenced using the names of those items that belong to it. In the linkage section, 01-level data items cannot be namedFILLER ALLOCATEstatement (see ALLOCATE) statement. In such cases, initialization will take place as per the documentation of that statement. [ REPORT SECTION.
~~~~~~ ~~~~~~~
{ Report-Description [ { Report-Group-Definition } ]... }... ]
{ { 01-Level-Constant } }
{ { 78-Level-Constant } }
{ 01-Level-Constant }
{ 78-Level-Constant }
RD report-name [ IS GLOBAL ]
~~ ~~~~~~
[ CODE IS literal-1 | identifier-1 ]
~~~~
[ { CONTROL IS } { FINAL }... ]
{ ~~~~~~~ } { ~~~~~ }
{ CONTROLS ARE } { identifier-2 }
~~~~~~~~
[ PAGE [ { LIMIT IS } ] [ { literal-2 } LINES ]
~~~~ { ~~~~~ } { identifier-3 } ~~~~
{ LIMITS ARE }
~~~~~~
[ literal-3 | identifier-4 COLUMNS|COLS ]
~~~~~~~ ~~~~
[ HEADING IS literal-4 | identifier-5 ]
~~~~~~~
[ FIRST DE|DETAIL IS literal-5 | identifier-6 ]
~~~~~ ~~ ~~~~~~
[ LAST CH|{CONTROL HEADING} IS literal-6 | identifier-7 ]
~~~~ ~~ ~~~~~~~ ~~~~~~~
[ LAST DE|DETAIL IS literal-7 | identifier-8 ]
~~~~ ~~ ~~~~~~
[ FOOTING IS literal-8 | identifier-9 ] ] .
~~~~~~~ TheCODE IS
AREandISare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. CONTROL ISandCONTROLS AREare interchangeable, as are thePAGE LIMITandPAGE LIMITSphrases. LINESmay be abbreviated asLINE COLUMNSmay be abbreviated asCOLS REPORT ISclause (see File/Sort-Description) must be described with a report description RD. GLOBALoption. PAGE LIMITS PAGE LIMITSclause is specified, the entire report will be generated as if it consists of a single arbitrarily long page. LINES AT TOPandLINES AT BOTTOMvalues specified on theLINAGEclause of theFDthisRDis linked to — see File/Sort-Description). HEADING FIRST DETAIL LAST CONTROL LAST DETAIL FOOTING PAGE LIMITclauses, assuming there is one: HEADING— the default is one (1) FIRST DETAIL— the HEADING value is used LAST CONTROL HEADING— the value fromLAST DETAILor, if that is absent, the value fromFOOTINGor, if that too is absent, the value fromPAGE LIMIT
LAST DETAIL— the value fromFOOTINGor, if that is absent, the value fromPAGE LIMIT
FOOTING— the value fromLAST DETAILor, if that is absent, the value fromPAGE LIMIT
PAGE LIMITclause to be valid, all of the following must be true: HEADINGnot >FIRST DETAIL
FIRST DETAILnot >LAST CONTROL HEADING
LAST CONTROL HEADINGnot >LAST DETAIL
LAST DETAILnot >FOOTING
CONTROL CONTROLclause, the report will contain no control breaks; this implies that there can be noCONTROL HEADINGorCONTROL FOOTINGreport groups defined for thisRD FINAL FINAL it must be the first control break named in theRD CONTROLclause are referencing data names defined in any data division section except for the report section. CONTROL HEADINGand/orCONTROL FOOTINGreport group defined in the report section for each <identifier-9>. GENERATEstatement (see GENERATE) is executed against a detail report group defined for thisRD the RWCS will check the contents of each <identifier-2> data item; whenever an <identifier-9>’s value has changed since the previous GENERATE, a control break condition will be in effect for that <identifier-2>. CONTROL FOOTINGfor each <identifier-2> having a control break (if any such report group is defined) will be presented. CONTROL HEADINGfor each <identifier-2> having a control break (if any such report group is defined) will be presented. CONTROL FOOTINGandCONTROL HEADINGreport groups will be presented in the sequence in which they are listed on theCONTROLclause. GENERATEbe presented. RDwill have the following allocated for it: PAGE-COUNTERspecial register (see Special Registers), which will contain the current report page number. INITIATEstatement (see INITIATE) is executed for the report and will be incremented by 1 each time the RWCS starts a new page of the report. PAGE-COUNTERwithin the report section will be implicitly qualified with the name of the report to which the report group referencing the register belongs. PAGE-COUNTERin the procedure division must be qualified with the appropriate report name if there are multipleRD defined. LINE-COUNTERspecial register , which will contain the current line number on the current page. RDmust be followed by at least one 01-level report group definition. 01 [ identifier-1 ]
[ LINE NUMBER IS { integer-1 [ [ ON NEXT PAGE ] } ]
~~~~ { ~~~~ ~~~~ }
{ +|PLUS integer-1 }
{ ~~~~ }
{ ON NEXT PAGE }
~~~~ ~~~~
[ NEXT GROUP IS { [ +|PLUS ] integer-2 } ]
~~~~ ~~~~~ { ~~~~ }
{ NEXT|{NEXT PAGE}|PAGE }
~~~~ ~~~~ ~~~~ ~~~~
[ TYPE IS { RH|{REPORT HEADING} } ]
~~~~ { ~~ ~~~~~~ ~~~~~~~ }
{ PH|{PAGE HEADING} }
{ ~~ ~~~~ ~~~~~~~ }
{ CH|{CONTROL HEADING} FINAL|identifier-2 }
{ ~~ ~~~~~~~ ~~~~~~~ ~~~~~ }
{ DE|DETAIL }
{ ~~ ~~~~~~ }
{ CF|{CONTROL FOOTING} FINAL|identifier-2 }
{ ~~ ~~~~~~~ ~~~~~~~ ~~~~~ }
{ PF|{PAGE FOOTING} }
{ ~~ ~~~~ ~~~~~~~ }
{ RF|{REPORT FOOTING} }
~~ ~~~~~~ ~~~~~~~
. [ REPORT-SECTION-Data-Item ]...
ISNUMBERandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. RHandREPORT HEADINGterms are interchangeable, as arePHandPAGE HEADINGCHandCONTROL HEADINGDEandDETAILCFandCONTROL FOOTINGPFandPAGE FOOTINGas well asRFandREPORT FOOTING RD TYPE(see TYPE) clause specifies the type of report group being defined. USE BEFORE REPORTING RD may named with the same <identifier-1>. There may, however, be multiple <identifier-1> definitions in different reports. In such instances, references to <identifier-1> must be qualified by the report name. level-number [ identifier-1 ]
[ BLANK WHEN ZERO ]
~~~~~ ~~~~
[ COLUMN [ { NUMBER IS } ] [ +|PLUS ] integer-1 ]
~~~ { ~~~~~~ } ~~~~
{ NUMBERS ARE }
~~~~~~~
[ GROUP INDICATE ]
~~~~~ ~~~~~~~~
[ JUSTIFIED RIGHT ]
~~~~
[ LINE NUMBER IS { integer-2 [ [ ON NEXT PAGE ] } ]
~~~~ { +|PLUS integer-2 ~~~~ ~~~~ }
{ ~~~~ }
{ ON NEXT PAGE }
~~~~ ~~~~
[ OCCURS [ integer-3 TO ] integer-4 TIMES
~~~~~~ ~~
[ DEPENDING ON identifier-2 ]
~~~~~~~~~
[ STEP integer-5 ]
~~~~
[ VARYING identifier-3 FROM { identifier-4 } BY { identifier-5 } ]
~~~~~~~ ~~~~ { integer-6 } ~~ { integer-7 }
[ PICTURE IS picture-string ]
~~~
[ PRESENT WHEN condition-name ]
~~~~~~~ ~~~~
[ SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ]
~~~~ ~~~~~~~ ~~~~~~~~ ~~~~~~~~
[ { SOURCE IS literal-1|identifier-6 [ ROUNDED ] } ]
{ ~~~~~~ ~~~~~~~ }
{ SUM OF { identifier-7 }... [ { RESET ON FINAL|identifier-8 } ] }
{ ~~~ { literal-2 } { ~~~~~ ~~~~~ } }
{ VALUE IS [ ALL ] literal-3 { UPON identifier-9 } }
~~~~~ ~~~ ~~~~
. [ REPORT-SECTION-Data-Item ]...
ISNUMBEROFONRIGHTTIMESandWHEN(BLANK) are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. COLUMNmay be abbreviated asCOL JUSTIFIEDmay be abbreviated asJUST PICTUREmay be abbreviated asPIC SOURCE(see SOURCE),SUM(see SUM) andVALUE(see VALUE) clauses, valid only on an elementary item, are mutually-exclusive of each other. PICTURE level-number [ identifier-1 | FILLER ]
~~~~~~
[ AUTO | AUTO-SKIP | AUTOTERMINATE ] [ BELL | BEEP ]
~~~~ ~~~~~~~~~ ~~~~~~~~~~~~~ ~~~~ ~~~~
[ BACKGROUND-COLOR|BACKGROUND-COLOUR IS integer-1 | identifier-2 ]
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
[ BLANK LINE|SCREEN ] [ ERASE EOL|EOS ]
~~~~~ ~~~~ ~~~~~~ ~~~~~ ~~~ ~~~
[ BLANK WHEN ZERO ] [ JUSTIFIED RIGHT ]
~~~~~ ~~~~ ~~~~
[ BLINK ] [ HIGHLIGHT | LOWLIGHT ] [ REVERSE-VIDEO ]
~~~~~ ~~~~~~~~~ ~~~~~~~~ ~~~~~~~~~~~~~
[ COLUMN NUMBER IS [ +|PLUS ] integer-2 | identifier-3 ]
~~~ ~~~~
[ FOREGROUND-COLOR|FOREGROUND-COLOUR IS integer-3 | identifier-4 ]
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
[ { FROM literal-1 | identifier-5 } ]
{ ~~~~ }
{ TO identifier-5 }
{ ~~ }
{ USING identifier-5 }
{ ~~~~~ }
{ VALUE IS [ ALL ] literal-1 }
~~~~~ ~~~
[ FULL | LENGTH-CHECK ] [ REQUIRED | EMPTY-CHECK ] [ SECURE | NO-ECHO ]
~~~~ ~~~~~~~~~~~~ ~~~~~~~~ ~~~~~~~~~~~ ~~~~~~ ~~~~~~~
[ LEFTLINE ] [ OVERLINE ] [ UNDERLINE ]
~~~~~~~~ ~~~~~~~~ ~~~~~~~~~
[ LINE NUMBER IS [ +|PLUS ] integer-4 | identifier-6 ]
~~~~ ~~~~
[ OCCURS integer-5 TIMES ]
~~~~~~
[ PICTURE IS picture-string ]
~~~
[ PROMPT [ CHARACTER IS literal-2 | identifier-7 ]
~~~~~~ ~~~~~~~~~
[ SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ]
~~~~ ~~~~~~~ ~~~~~~~~ ~~~~~~~~
. [ SCREEN-SECTION-Data-Item ]...
CHARACTERSEPARATEclause),ISNUMBERRIGHTTIMESandWHENare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. COLUMNmay be abbreviated asCOL PICTUREmay be abbreviated asPIC AUTOAUTO-SKIPandAUTOTERMINATE
BACKGROUND-COLORandBACKGROUND-COLOUR
BELLandBEEP
FOREGROUND-COLORandFOREGROUND-COLOUR
FULLandLENGTH-CHECK
REQUIREDandEMPTY-CHECK
SECUREandNO-ECHO
ACCEPT screen-data-itemstatement (see ACCEPT screen-data-item) orDISPLAY screen-data-itemstatement (see DISPLAY screen-data-item) statements. These screen layouts may define the entire available screen area or any subset of it. LINE(see LINE) orCOLUMN(see COLUMN) clauses, screen section fields will display on the console window beginning at whatever line/column coordinate is stated or implied by theACCEPT screen-data-itemorDISPLAY screen-data-itemstatement that presents the screen item. After a field is presented to the console window, the next field will be presented immediately following that field. LINEclause explicitly stated in the definition of a screen section data item will override anyLINEclause included on theACCEPT screen-data-itemorDISPLAY screen-data-itemstatement that presents that data item to the screen. The same is true ofCOLUMNclauses. 01 constant-name-1 CONSTANT [ IS GLOBAL ]
~~~~~~~~ ~~~~~~
{ AS { literal-1 } } .
{ { { BYTE-LENGTH } OF { identifier-1 } } }
{ { { ~~~~~~~~~~~ } { usage-name } } }
{ { { LENGTH } } }
{ ~~~~~~ }
{ FROM CDF-variable-name-1 }
~~~~ The 01-level constant is one of four types of compilation-time constants that can be declared within a program. The other three types are>>DEFINECDF directive (see >>DEFINE) constants,>>SETCDF directive (see >>SET) constants and 78-level constants (see 78-Level Data Items).
ASISandOFare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. GLOBALoption. USAGE(see USAGE) type — something not possible with the other types of constants. END PROGRAMorEND FUNCTIONis encountered in the input source. BYTE-LENGTH USAGEthat does not use aPICTURE(see PICTURE) clause. These would be any ofBINARY-C-LONGBINARY-CHARBINARY-DOUBLEBINARY-LONGBINARY-SHORTCOMP-1(orCOMPUTATIONAL-1,COMP-2(orCOMPUTATIONAL-2,FLOAT-DECIMAL-16FLOAT-DECIMAL-34FLOAT-LONGFLOAT-SHORTPOINTER orPROGRAM-POINTER BYTE-LENGTHclause will produce a numeric value for <constant-name-1> identical to that which would be returned by theBYTE-LENGTHintrinsic function executed against <identifier-1> or a data item declared with aUSAGEof <usage-name>. LENGTHclause will produce a numeric value for <constant-name-1> identical to that which would be returned by theLENGTHintrinsic function executed against <identifier-1> or a data item declared with aUSAGEof <usage-name>. Here is the listing of a GnuCOBOL program that uses 01-level constants to display the length (in bytes) of the various picture-less usage types.
IDENTIFICATION DIVISION.
PROGRAM-ID. Usage Lengths.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Len-BINARY-C-LONG CONSTANT AS LENGTH OF BINARY-C-LONG.
01 Len-BINARY-CHAR CONSTANT AS LENGTH OF BINARY-CHAR.
01 Len-BINARY-DOUBLE CONSTANT AS LENGTH OF BINARY-DOUBLE.
01 Len-BINARY-LONG CONSTANT AS LENGTH OF BINARY-LONG.
01 Len-BINARY-SHORT CONSTANT AS LENGTH OF BINARY-SHORT.
01 Len-COMP-1 CONSTANT AS LENGTH OF COMP-1.
01 Len-COMP-2 CONSTANT AS LENGTH OF COMP-2.
01 Len-FLOAT-DECIMAL-16 CONSTANT AS LENGTH OF FLOAT-DECIMAL-16.
01 Len-FLOAT-DECIMAL-34 CONSTANT AS LENGTH OF FLOAT-DECIMAL-34.
01 Len-FLOAT-LONG CONSTANT AS LENGTH OF FLOAT-LONG.
01 Len-FLOAT-SHORT CONSTANT AS LENGTH OF FLOAT-SHORT.
01 Len-POINTER CONSTANT AS LENGTH OF POINTER.
01 Len-PROGRAM-POINTER CONSTANT AS LENGTH OF PROGRAM-POINTER.
PROCEDURE DIVISION.
000-Main.
DISPLAY "On this system, with this build of GnuCOBOL, the"
DISPLAY "PICTURE-less USAGE's have these lengths (in bytes):"
DISPLAY " "
DISPLAY "BINARY-C-LONG: " Len-BINARY-C-LONG
DISPLAY "BINARY-CHAR: " Len-BINARY-CHAR
DISPLAY "BINARY-DOUBLE: " Len-BINARY-DOUBLE
DISPLAY "BINARY-LONG: " Len-BINARY-LONG
DISPLAY "BINARY-SHORT: " Len-BINARY-SHORT
DISPLAY "COMP-1: " Len-COMP-1
DISPLAY "COMP-2: " Len-COMP-2
DISPLAY "FLOAT-DECIMAL-16: " Len-FLOAT-DECIMAL-16
DISPLAY "FLOAT-DECIMAL-34: " Len-FLOAT-DECIMAL-34
DISPLAY "FLOAT-LONG: " Len-FLOAT-LONG
DISPLAY "FLOAT-SHORT: " Len-FLOAT-SHORT
DISPLAY "POINTER: " Len-POINTER
DISPLAY "PROGRAM-POINTER: " Len-PROGRAM-POINTER
STOP RUN
.
The output of this program, on a Windows 7 system with a 32-bit MinGW build of GnuCOBOL is:
On this system, with this build of GnuCOBOL, the
PICTURE-less USAGE's have these lengths (in bytes):
BINARY-C-LONG: 4
BINARY-CHAR: 1
BINARY-DOUBLE: 8
BINARY-LONG: 4
BINARY-SHORT: 2
COMP-1: 4
COMP-2: 8
FLOAT-DECIMAL-16: 8
FLOAT-DECIMAL-34: 16
FLOAT-LONG: 8
FLOAT-SHORT: 4
POINTER: 4
PROGRAM-POINTER: 4
66 identifier-1 RENAMES identifier-2 [ THRU|THROUGH identifier-3 ] .
~~~~~~~ ~~~~ ~~~~~~~
A 66-level data item regroups previously defined items by specifying alternative, possibly overlapping, groupings of elementary data items.
THRUandTHROUGHare interchangeable. RENAMESentries associated with one logical record must immediately follow that record’s last data description entry. 77 identifier-1 [ IS GLOBAL|EXTERNAL ]
~~~~~~ ~~~~~~~~
[ BASED ]
~~~~~
[ BLANK WHEN ZERO ]
~~~~~ ~~~~
[ JUSTIFIED RIGHT ]
~~~~
[ PICTURE IS picture-string ]
~~~
[ REDEFINES identifier-5 ]
~~~~~~~~~
[ SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ]
~~~~ ~~~~~~~ ~~~~~~~~ ~~~~~~~~
[ SYNCRONIZED|SYNCHRONISED [ LEFT|RIGHT ] ]
~~~~ ~~~~ ~~~~ ~~~~~
[ USAGE IS data-item-usage ]
~~~~~
[ VALUE IS [ ALL ] literal-1 ] .
~~~~~ ~~~ TheLEFTandRIGHT(SYNCRONIZED) clauses are syntactically recognized but are otherwise non-functional.
The intent of a 77-level item is to be able to create a stand-alone elementary data item.
CHARACTERISRIGHT(JUSTIFIED) andWHENare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. JUSTIFIEDmay be abbreviated asJUST the reserved wordPICTUREmay be abbreviated asPICand the reserved wordsSYNCRONIZEDandSYNCHRONISEDmay be abbreviated asSYNC 78 constant-name-1 VALUE IS literal-1 .
~~~~~
The 78-level constant is one of four types of compilation-time constants that can be declared within a program. The other three types are>>DEFINECDF directive (see >>DEFINE) constants,>>SETCDF directive (see >>SET) constants and 01-level constants (see 01-Level Constants).
ISis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. END PROGRAMorEND FUNCTIONis encountered in the input source. 88 condition-name-1 { VALUE IS } {literal-1 [ THRU|THROUGH literal-2 ]}...
{ ~~~~~ } ~~~~ ~~~~~~~
{ VALUES ARE }
~~~~~~
[ WHEN SET TO FALSE IS literal-3 ] .
~~~~~ Condition names are Boolean (i.e. TRUE / FALSE) data items that receive their TRUE and FALSE values based upon the values of the non 88-level data item whose definition they immediately follow.
AREISSETandTOare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. THRUandTHROUGHare interchangeable. VALUE(see VALUE) clause, <condition-name-1> will take on the value of TRUE. THROUGHclause allows a range of possible TRUE values to be specified. VALUEclause, <condition-name-1> will take on the value of FALSE. SET <condition-name-1> TO TRUEwill cause <condition-name-1>’s parent data item to take on the first value specified on <condition-name-1>’sVALUEclause. SET <condition-name-1> TO FALSEwill cause <condition-name-1>’s parent data item to take on the value specified on <condition-name-1>’sFALSEclause. If <condition-name-1> does not have aFALSEclause, theSET(see SET) statement will generate an error message at compilation time. ANY LENGTH ~~~ ~~~~~~
Data items declared with theANY LENGTHattribute have no fixed compile-time length. Such items may only be defined in the linkage section of a subprogram as they may only serve as subroutine argument descriptions. These items must have aPICTURE(see PICTURE) clause that specifies exactly one A, X or 9 symbol.
ANY LENGTHandBASED(see BASED) clauses cannot be used together in the same data item description. AUTO ~~~~
A field whose description includes this attribute will cause the cursor to automatically advance to the next input-enabled field of a screen if the field is completely filled with input data.
AUTOAUTO-SKIP(see AUTO-SKIP) andAUTOTERMINATE(see AUTOTERMINATE) clauses are interchangeable, and may not be used together in the same data item description. AUTO-SKIP ~~~~~~~~~
A field whose description includes this attribute will cause the cursor to automatically advance to the next input-enabled field of a screen if the field is completely filled with input data.
AUTO(see AUTO),AUTO-SKIPandAUTOTERMINATE(see AUTOTERMINATE) clauses are interchangeable, and may not be used together in the same data item description. AUTOTERMINATE ~~~~~~~~~~~~~
A field whose description includes this attribute will cause the cursor to automatically advance to the next input-enabled field of a screen if the field is completely filled with input data.
AUTO(see AUTO),AUTO-SKIP(see AUTO-SKIP) andAUTOTERMINATEclauses are interchangeable, and may not be used together in the same data item description. BACKGROUND-COLOR|BACKGROUND-COLOUR IS integer-1 | identifier-1 ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
This clause is used to specify the screen background color of the screen data item or the default screen background color of subordinate items if used on a group item.
ISis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. BACKGROUND-COLORandBACKGROUND-COLOURare interchangeable. See Color Palette and Video Attributes, for more information on screen colors and video attributes.
BASED ~~~~~
Data items declared withBASEDare allocated no storage at compilation time. At run-time, theALLOCATE(see ALLOCATE) orSET ADDRESS(see SET ADDRESS) statements are used to allocate space for and (optionally) initialize such items.
BASEDandANY LENGTH(see ANY LENGTH) clauses cannot be used together in the same data item description. BASEDclause may only be used on level 01 and level 77 data items. BEEP ~~~~
BEEPandBELL(see BELL) clauses are interchangeable, and may not be used together in the same data item description. BELL ~~~~
BEEP(see BEEP) andBELLclauses are interchangeable, and may not be used together in the same data item description. BLANK LINE|SCREEN ~~~~~ ~~~~ ~~~~~~
This clause will blank out either the entire screen (BLANK SCREEN) or just the line upon which data is about to be displayed (BLANK LINE).
BLANKclause. BLANK WHEN ZERO ~~~~~ ~~~~
This clause will cause that item’s value to be automatically transformed into spaces if a value of 0 is ever MOVEd to the item.
WHENis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. USAGE(see USAGE) ofDISPLAY BLINK ~~~~~
TheBLINKclause modifies the visual appearance of the displayed field by making the field contents blink.
See Color Palette and Video Attributes, for more information on screen colors and video attributes.
COLUMN [ { NUMBER IS } ] [ +|PLUS ] integer-1 ]
~~~ { NUMBERS ARE } ~~~~
COLUMN NUMBER IS [ +|PLUS ] integer-2 | identifier-3 ] ~~~ ~~~~
TheCOLUMNclause provides the means of stating in which column a field should be presented on the console window (screen section) or a report (report section).
AREISNUMBERandNUMBERSare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. COLUMNmay be abbreviated asCOL LINE(see LINE) clause. USAGE(see USAGE) other thanCOMPUTATIONAL-1orCOMPUTATIONAL-2 without editing symbols. The value of <identifier-1> at the time the screen data item is presented must be 1 or greater. Note that aCOMPUTATIONAL-1orCOMPUTATIONAL-2identifier will be accepted by the compiler, but will produce unpredictable results at run-time. COLUMN 5 or on a relative basis based upon the end of the previously-presented field (i.e.COLUMN PLUS 1. +may be used in lieu of the wordPLUS if desired; if symbol+is used, however, there must be at least one space separating it from <integer-1>. Failure to include this space will cause the symbol+sign to be simply treated as part of <integer-1> and will treat theCOLUMNclause as an absolute column specification rather than a relative one. COLUMN PLUS has slightly different behaviour depending upon the section in which the clause is used, as follows: COLUMN PLUSwill position the start of the new field’s value such that there are <integer-1> blank columns between the end of the previous field and the beginning of this field. If a report data item’s description includes theSOURCE(see SOURCE),SUM(see SUM) orVALUE(see VALUE) clause but has noCOLUMNclause,COLUMN PLUS 1will be assumed.
COLUMN PLUSwill position the new field so that it begins exactly <integer-1> or <identifier-1> characters past the last character of the previous field. Thus,COLUMN PLUS 1will leave no blank positions between the end of the previous field and the start of this one. If a screen data item’s description includes theFROM(see FROM),TO(see TO),USING(see USING) orVALUE(see VALUE) clause but has noCOLUMNclause, the new screen field will begin at the column coordinate of the last character of the previous field.
CONSTANT ~~~~~~~~
This option signifies that the 01-level data item in whose declarationCONSTANTis specified will be treated as a symbolic name for a literal value, usable wherever a literal of the appropriate type could be used.
EMPTY-CHECK ~~~~~~~~~~~
This clause forces the user to enter data into the field it is specified on (or into all subordinate input-capable fields ifEMPTY-CHECKis specified on a group item).
EMPTY-CHECKandREQUIRED(see REQUIRED) clauses are interchangeable, and may not be used together in the same data item description. ACCEPT screen-data-itemstatement (see ACCEPT screen-data-item) will ignore the Enter key and any other cursor-moving keystrokes that would cause the cursor to move to another screen item unless data has been entered into the field. Function keys will still be allowed to terminate theACCEPT EMPTY-CHECK ERASE EOL|EOS ~~~~~ ~~~ ~~~
ERASEwill blank-out screen contents from the location where the screen data item whose description contains this clause will be displayed, forward until the end of the screen ERASE EOS
ERASEclause. See Color Palette and Video Attributes, for more information on screen colors and video attributes.
EXTERNAL ~~~~~~~~
This clause marks a data item description,FDorSDsee File/Sort-Description as being shareable with other programs executed from the same execution thread.
EXTERNALclause on either an FD or an SD, the file description is capable of being shared between all programs executed from the same execution thread, provided anEXTERNALclause is coded with the file’s description in each program requiring it. This sharing allows the file to be opened, read and/or written and closed in different programs. This sharing applies to the record descriptions subordinate to the file description too. EXTERNALclause on the description of a data item, the data item is capable of being shared between all programs executed from the same execution thread, provided the data item is coded (with anEXTERNALclause) in each program requiring it. EXTERNALin a data item’s definition: WHEN SET TO FALSE IS literal-1
~~~~~
This clause, which may only appear on the definition of a level-88 condition name, is used to specify the value of the data item that serves as the parent of the level-88 condition name that will force the condition name to assume a value of FALSE.
ISSETTOandWHENare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. FOREGROUND-COLOR|FOREGROUND-COLOUR IS integer-1 | identifier-1 ~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
This clause is used to specify the color of text within a screen data item or the default text color of subordinate items if used on a group item.
ISis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. FOREGROUND-COLORandFOREGROUND-COLOURare interchangeable. See Color Palette and Video Attributes, for more information on screen colors and video attributes.
FROM literal-1 | identifier-5 ~~~~
This clause is used to specify either the data item a screen section field is to obtain it’s value from when the screen is displayed, or a literal that will specify the value of that same field.
FROMTO(see TO),USING(see USING) andVALUE(see VALUE) clauses are mutually-exclusive in any screen section data item’s definition. FULL ~~~~
TheFULLclause forces the user to enter data into the field it is specified on (or into all subordinate input-capable fields if specified on a group item) sufficient to fill every character position of the field.
FULLandLENGTH-CHECK(see LENGTH-CHECK) clauses are interchangeable, and may not be used together in the same data item description. ACCEPT screen-data-itemstatement (see ACCEPT screen-data-item) will ignore the Enter key and any other cursor-moving keystrokes that would cause the cursor to move to another screen item unless the proper amount of data has been entered into the field. Function keys will still be allowed to terminate theACCEPT however. FULL GLOBAL ~~~~~~
This clause marks a data item, 01-level constant,FD(see File/Sort-Description),SD(see File/Sort-Description) or anRD(see REPORT SECTION) as being shareable with any nested subprograms.
GLOBALclause on the description of a file or a report, that description is capable of being shared between a program and any nested subprograms within it, provided theFDSDorRDis coded (with aGLOBALclause) in each nested subprogram requiring it. This sharing allows the file to be opened, read and/or written and closed or the report to be initiated or terminated in those programs. Separately compiled programs may not share aGLOBALfile description, but they may share anEXTERNAL(see EXTERNAL) file description. This sharing applies to the record descriptions subordinate to the file description and the report groups subordinate to theRDalso. GLOBALclause on the description of a data item, the data item is capable of being shared between a program and any nested subprograms within it, provided the data item is coded (with aGLOBALclause) in each program requiring it. GLOBALin a data item’s definition: GROUP INDICATE ~~~~~ ~~~~~~~~
TheGROUP INDICATEclause specifies that the data item in whose definition the clause appears will be presented only in very limited circumstances.
DETAILreport group (see TYPE). INITIATE(see INITIATE) of the report. HIGHLIGHT ~~~~~~~~~
This clause controls the intensity of text FOREGROUND-COLOR(see FOREGROUND-COLOR)) by setting that intensity to its highest of three possible settings.
LOWLIGHT(see LOWLIGHT), are intended to provide a three-level intensity scheme LOWLIGHT… nothing (Normal) …HIGHLIGHT. See Color Palette and Video Attributes, for more information on screen colors and video attributes.
JUSTIFIED RIGHT ~~~~
The presence of aJUSTIFIED RIGHTclause in a data item’s definition alters the manner in which data is stored into the field from the default ’left-justified, space filled’ behaviour to ’right justified, space filled’.
RIGHTis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. JUSTIFIEDmay be abbreviated asJUST MOVE(see MOVE) statement as well as theFROM(see FROM),SOURCE(see SOURCE) andUSING(see USING) data item description clauses. JUSTIFIED RIGHTclause on that field’s description is irrelevant. JUSTIFIED RIGHTclause when the field size is different than that of the value being stored. In these examples, the symbol b represents a space. | Without JUSTIFIED | With JUSTIFIED |
|---|---|
01 A PIC X(6). |
01 A PIC X(6) JUSTIFIED RIGHT. |
MOVE |
MOVE |
| Result is ’ABCbbb’ | Result is ’bbbABC’ |
| Without JUSTIFIED | With JUSTIFIED |
|---|---|
01 A PIC X(6). |
01 A PIC X(6) JUSTIFIED RIGHT. |
MOVE |
MOVE |
| Result is ’ABCDEF’ | Result is ’DEFGHI’ |
LEFTLINE ~~~~~~~~
TheLEFTLINEclause will introduce a vertical line at the left edge of a screen field.
LEFTLINEOVERLINE(see OVERLINE) andUNDERLINE(see UNDERLINE) clauses may be used in any combination in a single field’s description. See Color Palette and Video Attributes, for more information on screen colors and video attributes.
LENGTH-CHECK ~~~~~~~~~~~~
TheLENGTH-CHECKclause forces the user to enter data into the field it is specified on (or into all subordinate input-capable fields if specified on a group item) sufficient to fill every character position of the field.
FULL(see FULL) andLENGTH-CHECKclauses are interchangeable, and may not be used together in the same data item description. ACCEPT screen-data-itemstatement (see ACCEPT screen-data-item) will ignore the Enter key and any other cursor-moving keystrokes that would cause the cursor to move to another screen item unless the proper amount of data has been entered into the field. Function keys will still be allowed to terminate theACCEPT however. LENGTH-CHECK LINE NUMBER IS { integer-2 [ [ ON NEXT PAGE ] }
~~~~ { ~~~~ ~~~~ }
{ +|PLUS integer-2 }
{ ~~~~ }
{ ON NEXT PAGE }
~~~~ ~~~~
[ LINE NUMBER IS [ +|PLUS ] integer-4 | identifier-6 ] ~~~~ ~~~~
This clause provides a means of explicitly stating on which line a field should be presented on the console window (screen section) or on a report (report section).
ISNUMBERandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. LINEclause: COLUMN(see COLUMN) clause. LINE 5 or on a relative basis based upon the previously-displayed line (i.e.LINE PLUS 1. +may be used in lieu of the wordPLUS if desired; if+is used, however, there must be at least one space separating it from <integer-1>. Failure to include this space will cause the+to be simply treated as part of <integer-1> and will treat the LINE clause as an absolute line specification rather than a relative one. NEXT PAGE LINEclause: COLUMN(see COLUMN) clause. USAGE(see USAGE) other thanCOMPUTATIONAL-1orCOMPUTATIONAL-2 without editing symbols. The value of <identifier-1> at the time the screen data item is presented must be 1 or greater. Note that aCOMPUTATIONAL-1orCOMPUTATIONAL-2identifier will be accepted by the compiler, but will produce unpredictable results at run-time. LINE 5 or on a relative basis based upon the previously-displayed line (i.e.LINE PLUS 1. +may be used in lieu of the wordPLUS if desired; if+is used, however, there must be at least one space separating it from <integer-1>. Failure to include this space will cause the+to be simply treated as part of <integer-1> and will treat theLINEclause as an absolute line specification rather than a relative one. FROM(see FROM),TO(see TO),USING(see USING) orVALUE(see VALUE) clause but has no LINE clause, the "current screen line" will be assumed. LOWLIGHT ~~~~~~~~
TheLOWLIGHTclause controls the intensity of text FOREGROUND-COLOR by setting that intensity to its lowest of three possible settings.
HIGHLIGHT(see HIGHLIGHT), are intended to provide a three-level intensity scheme LOWLIGHT… nothing (Normal) …HIGHLIGHT. In environments such as a Windows console where only two levels of intensity are supported,LOWLIGHTis the same as leaving this clause off altogether. See Color Palette and Video Attributes, for more information on screen colors and video attributes.
NEXT GROUP IS { [ +|PLUS ] integer-2 }
~~~~ ~~~~~ { ~~~~ }
{ NEXT|{NEXT PAGE}|PAGE }
~~~~ ~~~~ ~~~~ ~~~~
This clause defines any rules for where the next group to be presented on a report will begin, line-wise, with respect to the last line of the group in which this clause appears.
ISis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. NEXT LINE NUMBERclause in order to also contain aNEXT GROUPclause. RD(see REPORT SECTION) in which the report group containing aNEXT GROUPclause does not contain aPAGE LIMITSclause, only thePLUS integer-1option may be specified. NEXT PAGEoption cannot be used in aPAGE FOOTING NEXT GROUPoption cannot be specified in either aREPORT HEADINGor aPAGE HEADING NEXT GROUPwill be in addition to any line spacing defined by the next-presented group’sLINE NUMBERclause. NO-ECHO ~~~~~~~
TheNO-ECHOclause will cause all data entered into the field to appear on the screen as asterisks.
NO-ECHOandSECURE(see SECURE) clauses are interchangeable, and may not be used together in the same data item description. USING(see USING) orTO(see TO) clause). See Color Palette and Video Attributes, for more information on screen colors and video attributes.
OCCURS [ integer-1 TO ] integer-2 TIMES
~~~~~~ ~~
[ DEPENDING ON identifier-1 ]
~~~~~~~~~
[ STEP integer-3 ]
~~~~
[ VARYING identifier-2 FROM { identifier-3 } BY { identifier-4 } ]
~~~~~~~ ~~~~ { integer-4 } ~~ { integer-5 }
OCCURS integer-2 TIMES ~~~~~~
OCCURS [ integer-1 TO ] integer-2 TIMES
~~~~~~ ~~
[ DEPENDING ON identifier-1 ]
~~~~~~~~~
[ ASCENDING|DESCENDING KEY IS identifier-5... ]...
~~~~~~~~~ ~~~~~~~~~~
[ INDEXED BY identifier-6 ]
~~~~~~~
TheOCCURSclause is used to create a data structure called a table, where entries in that structure repeat multiple times.
BY(INDEXED),ISKEYONandTIMESare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. 05 QUARTERLY-REVENUE OCCURS 4 TIMES PIC 9(7)V99.
This will allocate the following:
QUARTERLY-REVENUE(1) QUARTERLY-REVENUE(2) QUARTERLY-REVENUE(3) QUARTERLY-REVENUE(4)
Each occurrence is referenced using the subscript syntax (a numeric literal, arithmetic expression or numeric identifier enclosed within parenthesis) shown above.
OCCURSclause may be used at the group level too, in which case the entire group structure repeats, as follows: 05 GRP OCCURS 3 TIMES.
10 A PIC X(1).
10 B PIC X(1).
10 C PIC X(1).
This would allow references to any of the following:
GRP(1) - includes A(1), B(1) and C(1) GRP(2) - includes A(2), B(2) and C(2) GRP(3) - includes A(3), B(3) and C(3)
or each A,B,C item could be referenced as follows:
A(1) - Character #1 of GRP(1) B(1) - Character #2 of GRP(1) C(1) - Character #3 of GRP(1) A(2) - Character #1 of GRP(2) B(2) - Character #2 of GRP(2) C(2) - Character #3 of GRP(2) A(3) - Character #1 of GRP(3) B(3) - Character #2 of GRP(3) C(3) - Character #3 of GRP(3)
DEPENDING ON SEARCH(see SEARCH),SEARCH ALL(see SEARCH ALL) andSORT(see SORT) statements for explanations of theKEY OCCURSclause cannot be specified in a data description entry that has a level number of 01, 66, 77, or 88, although it is valid in data items described subordinate to an 01-level data item. OCCURSused in the report section: STEP VARYING OCCURScapabilities ofSTEPandVARYING Both assume the definition of the following table exists in working-storage: 05 SALES OCCURS 4 TIMES PIC 9(7)V99. First, the "Hard Way":
10 COL 7 PIC $(7)9.99 SOURCE SALES(1). 10 COL 17 PIC $(7)9.99 SOURCE SALES(2). 10 COL 27 PIC $(7)9.99 SOURCE SALES(3). 10 COL 37 PIC $(7)9.99 SOURCE SALES(4).
And then usingSTEPandVARYING
10 COL 7 OCCURS 4 TIMES STEP 10 VARYING QTR FROM 1 BY 1
PIC $(7)9.99 SOURCE SALES(QTR).
OVERLINE ~~~~~~~~
TheOVERLINEclause will introduce a horizontal line at the top edge of a screen field.
LEFTLINE(see LEFTLINE),OVERLINEandUNDERLINE(see UNDERLINE) clauses may be used in any combination in a single field’s description. See Color Palette and Video Attributes, for more information on screen colors and video attributes.
PICTURE IS picture-string ~~~
The picture clause defines the class (numeric, alphabetic or alphanumeric), size and format of the data that may be contained by the data item being defined. Sometimes this role is assisted by theUSAGE(see USAGE) clause, and in a few instances will be assumed entirely by that clause.
ISis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. PICTUREmay be abbreviated asPIC Most programmers prefer to use the latter. $*+,-./0(zero),9ABCRDBSVXandZ PIC 9999/99/99— for example, the repetition can be specified using a parenthetic repeat count, as inPIC 9(4)/9(2)/9(2) Using repeat counts is optional and their use (or not) is entirely at the discretion of the programmer. Many programmers use repetition for small sequences PIC XXX and repeat counts for larger ones PIC 9(9) ADefines storage reserved for a single alphabetic character AZaz.
NDefines storage reserved for a single character in the computer’s ’National Character set’
XDefines storage reserved for a single alphanumeric character (any character).
9Defines storage reserved for a single numeric digit character 09.
Typically, only one kind of each of those symbols is used in the same picture clause, but that isn’t a requirement. Data items that, of the three symbols above, use nothing butApicture symbols are known as ’Alphabetic Data Items’
If you need to allocate space for a data item whose format is two letters followed by five digits followed by three letters, you could use the <picture-string>AA99999AAAA(2)9(5)A(3)XXXXXXXXXXorX(10) There is absolutely no functional difference whatsoever between the four — none of them provide any functionality the others do not. The first two probably make for better documentation of the expected field contents, but they don’t provide any run-time enforcement capabilities.
As far as enforcement goes, however, both alphabetic and numeric picture strings do provide for both compile-time and run-time enforcement capabilities. In the case of compilation enforcement, the compiler can issue warning messages if you attempt to specify a non-numeric value for a numeric data item or if you attempt toMOVE(see MOVE) a non-numeric data item to one that is numeric. Similar capabilities exist for alphabetic data items. At run-time, you may use a special class test (see Class Conditions) to determine if the contents of a data item are entirely numeric or entirely alphabetic.
PDefines an implied digit position that will be considered to be a zero when the data item is referenced at run-time. This symbol is used to allow data items that will contain very large values to be allocated using less storage by assuming a certain number of trailing zeros (one perP to exist at the end of values.
ThePsymbol is not allowed in conjunction withN
ThePsymbol may only be used at the beginning or end of a picture clause.
Pis a repeatable symbol.
All computations andMOVE(see MOVE) operations involving such a data item will behave as if the zeros were actually there.
For example, let’s say you need to allocate a data item that contains however many millions of dollars of revenue your company has in gross revenues this year:
01 Gross-Revenue PIC 9(9).
In which case 9 characters of storage will be reserved. The values 000000000 through 999999999 will represent the gross-revenues. But, if only the millions are tracked (meaning the last six digits are always going to be 0), you could define the field as:
01 Gross-Revenue PIC 9(3)P(6).
Whenever Gross-Revenue is referenced in calculations, or whenever its value is moved to another data item, the value of Gross-Revenue will be treated as if it is nnn000000, where ’nnn’ is the actual value in storage.
If you wanted to store the value 128 million into that field, you would do so as if theP were9:
MOVE 128000000 TO Gross-Revenue
ADISPLAY(see DISPLAY) of a data item containingPsymbols is a little strange. The value displayed will be what is actually in storage, but the total size of the displayed value will be as if thePsymbols had been9. Thus, after the above statement established a value for Gross-Revenue, aDISPLAY Gross-Revenuewould produce output of ’000000128’.
SThis symbol, if used, must be the very first symbol in thePICTUREvalue. ASindicates that the data item isSigned meaning that negative values are possible for this data item. Without anS any negative values stored into this data item via aMOVEor arithmetic statement will have the negative sign stripped from it (in effect becoming the absolute value).
TheSsymbol is not allowed in conjunction withN
TheSsymbol may only occur once in a picture string. See SIGN IS, for further discussion of how negative values may be stored in a numeric data item.
VThis symbol is used to define where an implied decimal-point (if any) is located in a numeric item. Just as there may only be a single decimal point in a number so may there be no more than oneVin aPICTURE Implied decimal points occupy no space in storage — they just specify how values are used. For example, if the value1234is in storage in a field defined as PIC 999V9, that value would be treated as 123.4 in any statements that referenced it.
TheVsymbol is not allowed in conjunction withN
TheVsymbol may only occur once in a picture string.
BTheBediting symbol introduces a blank into the field value for each occurrence.
MultipleBsymbols may be coded.
The following example will format a ten digit number (presumably a telephone number) into a### ### ####layout:
...
05 Phone-Number PIC 9(3)B9(3)B9(4).
...
MOVE 5185551212 TO Phone-Number
DISPLAY Phone-Number
This code will display518 555 1212
0The0(zero) editing symbol introduces one "0" character into the field value for each occurrence in the picture string.
Multiple0symbols may be coded.
Here’s an example:
...
05 Output-Item PIC 909090909.
...
MOVE 12345 TO Output-Item
DISPLAY Output-Item
The above will display102030405
/The/editing symbol inserts one "/" character into the field value for each occurrence in the picture string.
Multiple/symbols may be coded.
This editing symbol is most-frequently used to format dates, as follows:
...
05 Year-Month-Day PIC 9(4)/9(2)/9(2).
...
MOVE 20140207 TO Year-Month-Day
DISPLAY Year-Month-Day
This example displays2014/02/07
.The.symbol inserts a decimal point into a numeric field value. When the contents of a numeric data item sending field are moved into a receiving data item whose picture clause contains the.editing symbol, implied V or actual decimal point in the sending data item or literal, respectively, will be aligned with the.symbol in the receiving field. Digits are then transferred from the sending to the receiving field outward from the sending field’s "V" or ".", truncating sending digits if there aren’t enough positions in the receiving field. Any digit positions in the receiving field that don’t receive digits from the sending field, if any, will be set to 0.
The.symbol is not allowed in conjunction withN
An example will probably help:
...
05 Source-Field PIC 9(2)V9 VALUE 7.2.
05 Dest-Field PIC 9(5).9(2).
...
MOVE 1234567.89 TO Dest-Field
DISPLAY Dest-Field
MOVE 19 TO Dest-Field
DISPLAY Dest-Field
MOVE Source-Field TO Dest-Field
DISPLAY Dest-Field
The example will display three results —34567.8900019.00and00007.20
Both data item definitions appear to have two decimal points in their picture clauses. They actually don’t, because the last character of every data item definition is always a period — the period that ends the definition.
,The,symbol serves as a thousands separator. Many times, you’ll see large numbers formatted with these symbols — for example, 123,456,789. This can be accomplished easily by adding thousands separator symbols to a picture string. Thousands separator symbols that aren’t needed will behave as if they were9.
The,symbol is not allowed in conjunction withN
Here’s an example:
...
05 My-Lottery-Winnings PIC 9(3),9(3),9(3).
...
MOVE 12345 TO My-Lottery-Winnings
DISPLAY My-Lottery-Winnings
The value0000012,345(a very disappointing one for my retirement plans, but a good thousands separator demo) will be displayed. Notice how, since the first comma wasn’t needed due to the meagre amount I won, it behaved like another "9".
If desired, you may reverse the roles of the.and,editing symbols by specifyingDECIMAL POINT IS COMMAin theSPECIAL-NAMES(see SPECIAL-NAMES) paragraph.
+-CRorDBsymbols may be used in a picture clause. In this context, when any of these symbols are used in a <picture-string>, they must be at the end. The+-and/or currency symbols may also be used as floating editing symbols at the beginning of the <picture-string> — a subject that will be covered in the next numbered paragraph. +If the value of the numeric value moved into the field is positive (0 or greater), a "+" character will be inserted. If the value is negative (less than 0), a "-" character is inserted.
The+symbol is not allowed in conjunction withN
-If the value of the numeric value moved into the field is positive (0 or greater), a space will be inserted. If the value is negative (less than 0), a "-" character is inserted.
The-symbol is not allowed in conjunction withN
CRThis symbol is coded as the two characters "C" and "R". If the value of the numeric value moved into the field is positive (0 or greater), two spaces will be inserted. If the value is negative (less than 0), the characters "CR" (credit) are inserted.
TheCRsymbol is not allowed in conjunction withN
DBThis symbol is coded as the two characters "D" and "B". If the value of the numeric value moved into the field is positive (0 or greater), two spaces will be inserted. If the value is negative (less than 0), the characters "DB" (debit) are inserted.
TheDBsymbol is not allowed in conjunction withN
$Regardless of the value moved into the field, this symbol will insert the currency symbol into the data item’s value in the position where it occurs in the <picture-string> (see SPECIAL-NAMES).
The$symbol is not allowed in conjunction withN
9editing symbols in the <picture-string> of a numeric data item. Using these symbols transforms that numeric data item into a numerid edited data item, which can no longer be used in calculations or subscripts. 9 until such point as all digits in the numeric value are exhausted and leading zeros are about to be inserted. In effect, these editing symbols define what should happen to those leading zero. $Of those currency symbols that correspond to character positions in which leading zeros reside, the right-most will have its "0" value replaced by the currency symbol in-effect for the program (see SPECIAL-NAMES). Any remaining leading zero values occupying positions described by this symbol will be replaced by spaces.
The$symbol is not allowed in conjunction withN
Any currency symbol coded to the right of a.will be treated exactly like a9
*This symbol is referred to as a check protection symbol. All check-protection symbols that correspond to character positions in which leading zeros reside will have their "0" values replaced by "*".
The*symbol is not allowed in conjunction withN
Any check-suppression symbol coded to the right of a.will be treated exactly like a9
+Of those+symbols that correspond to character positions in which leading zeros reside, the right-most will have its "0" value replaced by a "+" if the value in the data item is zero or greater or a "-" otherwise. Any remaining leading zero values occupying positions described by this symbol will be replaced by spaces. You cannot use both+and-in the same <picture-string>.
The+symbol is not allowed in conjunction withN
Any+symbol coded to the right of a.will be treated exactly like a9
-Of those-symbols that correspond to character positions in which leading zeros reside, the right-most will have its "0" value replaced by a space if the value in the data item is zero or greater or a "-" otherwise. Any remaining leading zero values occupying positions described by this symbol will be replaced by spaces. You cannot use both+and-in the same <picture-string>.
The-symbol is not allowed in conjunction withN
Any-symbol coded to the right of a.will be treated exactly like a9
ZAllZsymbols that correspond to character positions in which leading zeros reside will have their "0" values replaced by spaces.
Any zero-suppression symbol coded to the right of a.will be treated exactly like a9
Zand*should not be coded in the same <picture-string>
+and-should not be coded in the same <picture-string>
When multiple floating symbols are coded, even if there is only one of them used they will all be considered floating and will all be able to assume each other’s properties. For example, if a data item has aPIC +$ZZZZ9.99<picture-string>, and a value of 1 is moved to that field at run-time, the resulting value will be (the b symbol represents a space)bbbb+$1.00 This is not consistent with many other COBOL implementations, where the result would have been+$bbbb1.00
Most other COBOL implementations reject the use of multiple occurrences of multiple floating editing symbols. For example, they would reject <picture-string>s such as+++$$$9.99$$$ZZZ9.99and so on. GnuCOBOL accepts these. Programmers creating GnuCOBOL programs should avoid such <picture-string>s if there is any likelihood that those programs may be used with other COBOL implementations.
PRESENT WHEN condition-name ~~~~~~~ ~~~~
This clause names an existingCondition Name(see Condition Names) that will serve as a switch controlling the presentation or suppression of a report group.
GENERATEstatement (see GENERATE) causes a report group to be presented, the presentation of that group will be suppressed. PROMPT [ CHARACTER IS literal-1 | identifier-1 ] ~~~~~~ ~~~~~~~~~
This clause defines the character that will be used as the fill-character for any input fields on the screen.
ISis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. CHARACTERspecification be coded, or should thePROMPTclause be absent altogether, is an underscore ("_"). See Color Palette and Video Attributes, for more information on screen colors and video attributes.
PROTECTED SIZE IS { identifier }
~~~~~~~~ ~~~~ { integer }
PROTECTEDextended clause will effect the specified field to be limited in size, regardless of the picture size. OR DOES IT? REDEFINES identifier-1 ~~~~~~~~~
TheREDEFINESclause causes the data item in who’s definition theREDEFINESclause is specified (hereafter referred to as the redefines object) to occupy the same physical storage space as <identifier-1> (hereafter referred to as the redefines subject).
nrepresents the level number of the object, then no other data items with level numbernmay be defined between the subject and object data items unless they too areREDEFINESof the subject. nrepresents the level number of the object, then no other data items with a level number numerically less thannmay be defined between the subject and object data items. OCCURS(see OCCURS) clause may be part of the definition of either the subject or object data items. Either or both, however, may be group items that contain data items withOCCURSclauses. VALUE(see VALUE) clause may be defined on the object data item, and no data items subordinate to the object data item may haveVALUEclauses, with the exception of level-88 condition names. RENAMES identifier-1 [ THRU|THROUGH identifier-2 ~~~~~~~ ~~~~ ~~~~~~~
TheRENAMESclause regroups previously defined items by specifying alternative, possibly overlapping, groupings of elementary data items.
THRUandTHROUGHare interchangeable. RENAMESclause. REQUIRED ~~~~~~~~
This clause forces the user to enter data into the field it is specified on (or into all subordinate input-capable fields ifREQUIREDis specified on a group item).
EMPTY-CHECK(see EMPTY-CHECK) andREQUIREDclauses are interchangeable, and may not be used together in the same data item description. ACCEPT screen-data-itemstatement (see ACCEPT screen-data-item) will ignore the Enter key and any other cursor-moving keystrokes that would cause the cursor to move to another screen item unless data has been entered into the field. Function keys will still be allowed to terminate theACCEPT REQUIRED REVERSE-VIDEO ~~~~~~~~~~~~~
TheREVERSE-VIDEOattribute swaps the specified or impliedFOREGROUND-COLOR(see FOREGROUND-COLOR) andBACKGROUND-COLOR(see BACKGROUND-COLOR) attributes for the field whose definition contains this clause (or all subordinate fields if used on a group item).
See Color Palette and Video Attributes, for more information on screen colors and video attributes.
SECURE ~~~~~~
This clause will cause all data entered into the field to appear on the screen as asterisks.
NO-ECHO(see NO-ECHO) andSECUREclauses are interchangeable, and may not be used together in the same data item description. USING(see USING) orTO(see TO) clause). See Color Palette and Video Attributes, for more information on screen colors and video attributes.
SIGN IS LEADING|TRAILING [ SEPARATE CHARACTER ] ~~~~ ~~~~~~~ ~~~~~~~~ ~~~~~~~~
This clause, allowable only forUSAGE DISPLAYnumeric data items, specifies how anSsymbol will be interpreted in a data item’s picture clause.
CHARACTERandISare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. SEPARATE CHARACTER | First/Last Digit | Value For Positive | Value for Negative |
|---|---|---|
| 0 | 0 | p |
| 1 | 1 | q |
| 2 | 2 | r |
| 3 | 3 | s |
| 4 | 4 | t |
| 5 | 5 | u |
| 6 | 6 | v |
| 7 | 7 | w |
| 8 | 8 | x |
| 9 | 9 | y |
SEPARATE CHARACTERclause is used, then an actual+or-character will be inserted into the field’s value as the first LEADING or last TRAILING character. Note that having this character embedded within the data item’s storage does not prevent the data item from being used as a source field in arithmetic operations. SEPARATE CHARACTERis specified, theSsymbol in the data item’sPICTUREmust be counted when determining the data item’s size. +or-character embedded within the data item’s storage prevents the data item from being used as a source field in arithmetic operations. SOURCE IS literal-1 | identifier-1 [ ROUNDED ] ~~~~~~ ~~~~~~~
This clause logically attaches a report section data item to another data item defined elsewhere in the data division.
ISis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. PAGE-COUNTER PICTURE(see PICTURE) of the report data item must be such that it would be legal toMOVE(see MOVE) the specified literal or identifier to a data item with thatPICTURE ROUNDEDoption comes into play should the number of digits to the right of an actual or assumed decimal point be different between the specified literal or identifier value (the "source value") and thePICTUREspecified for the field in whose definition theSOURCEclause appears (the "target field"). WithoutROUNDED excess digits in the source value will simply be truncated to fit the target field. WithROUNDED the source value will be arithmetically rounded to fit the target field. See ROUNDED, for information on theNEAREST-AWAY-FROM-ZEROrounding rule, which is the one that will apply. SUM OF { identifier-7 }... [ { RESET ON FINAL|identifier-8 } ]
~~~ { literal-2 } { ~~~~~ ~~~~~ }
{ UPON identifier-9 }
~~~~
TheSUMclause establishes a summation counter whose value will be arithmetically calculated whenever the field is presented.
OFandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. SUMclause may only appear in aCONTROL FOOTINGreport group. SUMclause appears has been assigned it’s own identifier name, and that name is notFILLER then that data item is referred to as a sum counter. SUMclause appears or they must be defined in a report data item that exists at a lower level in this report’s control hierarchy. See Control Hierarchy, for additional information. PICTUREof the report data item in who’s description thisSUMclause appears in must be such that it would be legal toMOVE(see MOVE) the specified <identifier-7> or <literal-2> value to a data item with thatPICTURE UPON SUMclause appears. UPONclause limits theSUMclause to adding the specified numeric literal or identifier value into the sum counter only when aGENERATE <identifier-9>statement is executed. UPONclause specified, the value of <identifier-7> or <literal-2> will be added into the sum counter whenever aGENERATE(see GENERATE) of any detail report group in the report is executed. UPONclause is meaningless. RESET RESEToption is coded,FINALor <identifier-8> (whichever is coded on theRESET must be one of the report’s control breaks specified on theCONTROLSclause. RESEToption coded, the sum counter will be reset back to zero after each time the control footing containing theSUMclause is presented. This is the typical behaviour that would be expected. SUMcounter only when the control footing for a control break higher in the control hierarchy is presented, specify that higher control break on theRESEToption. SYNCRONIZED|SYNCHRONISED [ LEFT|RIGHT ] ~~~~ ~~~~ ~~~~ ~~~~~
TheLEFTandRIGHT(SYNCRONIZED) clauses are syntactically recognized but are otherwise non-functional.
This optional clause optimizes the storage of binary numeric items to store them in such a manner as to make it as fast as possible for the CPU to fetch them.
SYNCRONIZEDandSYNCHRONISEDare interchangeable, and may be abbreviated asSYNC SYNCRONIZEDclause is coded on anything but a numeric data item with aUSAGE(see USAGE) that specifies storage of data in a binary form, theSYNCRONIZEDclause will be ignored. TO identifier-5 ~~
This clause logically attaches a screen section data item to another data item defined elsewhere in the data division.
TOclause is used to define a data-entry field with no initial value; when a value is entered, it will be saved to the specified identifier. FROM(see FROM),TOUSING(see USING) andVALUE(see VALUE) clauses are mutually-exclusive in any screen section data item’s definition. [ TYPE IS { RH|{REPORT HEADING} } ]
~~~~ { ~~ ~~~~~~ ~~~~~~~ }
{ PH|{PAGE HEADING} }
{ ~~ ~~~~ ~~~~~~~ }
{ CH|{CONTROL HEADING} FINAL|identifier-2 }
{ ~~ ~~~~~~~ ~~~~~~~ ~~~~~ }
{ DE|DETAIL }
{ ~~ ~~~~~~ }
{ CF|{CONTROL FOOTING} FINAL|identifier-2 }
{ ~~ ~~~~~~~ ~~~~~~~ ~~~~~ }
{ PF|{PAGE FOOTING} }
{ ~~ ~~~~ ~~~~~~~ }
{ RF|{REPORT FOOTING} }
~~ ~~~~~~ ~~~~~~~
This clause defines the type of report group that is being defined for a report.
RDdefined with aTYPEofREPORT HEADINGPAGE HEADINGPAGE FOOTINGandREPORT FOOTING CONTROL HEADINGor aCONTROL FOOTINGor both specified for each entry specified on theCONTROLS AREclause of theRD UNDERLINE ~~~~~~~~~
TheUNDERLINEclause will introduce a horizontal line at the bottom edge of a screen field.
LEFTLINE(see LEFTLINE),OVERLINE(see OVERLINE) andUNDERLINEclauses may be used in any combination in a single field’s description. See Color Palette and Video Attributes, for more information on screen colors and video attributes.
USAGE IS data-item-usage ~~~~~
TheUSAGEclause defines the format that will be used to store the value of a data item.
ISis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. BINARY~~~~~~
| Range of Values: | Defined by the quantity of9 and the presence or absence of anSin thePICTURE
|
|
| Storage Format: | Compatible Binary Integer | |
| Negative Values Allowed?: | IfPICTUREcontainsS
|
|
PICTUREUsed?: |
Yes |
BINARY-C-LONG [ SIGNED ]~~~~~~~~~~~~~
Same asBINARY-DOUBLE SIGNED
|
BINARY-C-LONG UNSIGNED~~~~~~~~~~~~~ ~~~~~~~~
| Range of Values: | Typically 0 to 4,294,967,295 | |
| Storage Format: | Native Binary Integer | |
| Negative Values Allowed?: | No | |
PICTUREUsed?: |
No |
BINARY-CHAR [ SIGNED ]~~~~~~~~~~~
| Range of Values: | -128 to 127 | |
| Storage Format: | Native Binary Integer | |
| Negative Values Allowed?: | Yes | |
PICTUREUsed?: |
No |
BINARY-CHAR UNSIGNED~~~~~~~~~~~ ~~~~~~~~
| Range of Values: | 0 to 255 | |
| Storage Format: | Native Binary Integer | |
| Negative Values Allowed?: | No | |
PICTUREUsed?: |
No |
BINARY-DOUBLE [ SIGNED ]~~~~~~~~~~~~~
| Range of Values: | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 | |
| Storage Format: | Native Binary Integer | |
| Negative Values Allowed?: | Yes | |
PICTUREUsed?: |
No |
BINARY-DOUBLE UNSIGNED~~~~~~~~~~~~~ ~~~~~~~~
| Range of Values: | 0 to 18,446,744,073,709,551,615 | |
| Storage Format: | Native Binary Integer | |
| Negative Values Allowed?: | No | |
PICTUREUsed?: |
No |
BINARY-INT~~~~~~~~~~
Same asBINARY-LONG SIGNED
|
BINARY-LONG [ SIGNED ]~~~~~~~~~~~
| Range of Values: | -2,147,483,648 2,147,483,647 | |
| Storage Format: | Native Binary Integer | |
| Negative Values Allowed?: | Yes | |
PICTUREUsed?: |
No |
BINARY-LONG UNSIGNED~~~~~~~~~~~ ~~~~~~~~
| Range of Values: | 0 to 4,294,967,295 | |
| Storage Format: | Native Binary Integer | |
| Negative Values Allowed?: | No | |
PICTUREUsed?: |
No |
BINARY-LONG-LONG~~~~~~~~~~~~~~~~
Same asBINARY-DOUBLE SIGNED
|
BINARY-SHORT [ SIGNED ]~~~~~~~~~~~~
| Range of Values: | -32,768 to 32,767 | |
| Storage Format: | Native Binary Integer | |
| Negative Values Allowed?: | Yes | |
PICTUREUsed?: |
No |
BINARY-SHORT UNSIGNED~~~~~~~~~~~~ ~~~~~~~~
| Range of Values: | 0 to 65,535 | |
| Storage Format: | Native Binary Integer | |
| Negative Values Allowed?: | No | |
PICTUREUsed?: |
No |
COMPUTATIONAL~~~~
Same asBINARY
|
COMP[UTATIONAL]-1~~~~ ~~
Same asFLOAT-SHORT
|
COMP[UTATIONAL]-2~~~~ ~~
Same asFLOAT-LONG
|
COMP[UTATIONAL]-3~~~~ ~~
Same asPACKED-DECIMAL
|
COMP[UTATIONAL]-4~~~~ ~~
Same asBINARY
|
COMP[UTATIONAL]-5~~~~ ~~
| Range of Values: | Depends on number of9 in thePICTUREand thebinary-sizesetting of the configuration file used to compile the program |
|
| Storage Format: | Native Binary Integer | |
| Negative Values Allowed?: | IfPICTUREcontainsS
|
|
PICTUREUsed?: |
Yes |
COMP[UTATIONAL]-6~~~~ ~~
| Range of Values: | Defined by the quantity of9 and the presence or absence of anSin thePICTURE
|
|
| Storage Format: | Unsigned Packed Decimal | |
| Negative Values Allowed?: | No | |
PICTUREUsed?: |
Yes |
COMP[UTATIONAL]-X~~~~ ~~
| Range of Values: | If used withPIC X allocates one byte of storage perX range of values is 0 to max storable in that many bytes. If used withPIC 9 range of values depends on number of9 in PICTURE |
|
| Storage Format: | Native unsigned (X) or signed (9) Binary | |
| Negative Values Allowed?: | IfPICTURE9 and containsS
|
|
PICTUREUsed?: |
Yes |
DISPLAY~~~~~~~
| Range of Values: | Depends onPICTURE One character per X, A, 9, period, $, Z, 0, *, S (ifSEPARATE CHARACTERspecified), +, - or B symbol inPICTURE Add 2 more bytes if theDBorCRediting symbol is used |
|
| Storage Format: | Characters | |
| Negative Values Allowed?: | IfPICTUREcontainsS
|
|
PICTUREUsed?: |
Yes |
FLOAT-DECIMAL-16~~~~~~~~~~~~~~~~
| Range of Values: | 9.999999999999999×10^384 to 9.999999999999999×10^384 | |
| Storage Format: | Native IEEE 754 Decimal64 Floating-point | |
| Negative Values Allowed?: | Yes | |
PICTUREUsed?: |
No |
FLOAT-DECIMAL-34~~~~~~~~~~~~~~~~
| Range of Values: | -9.99999...×10^6144 to 9.99999...×10^6144 | |
| Storage Format: | Native IEEE 754 Decimal128 Floating-point | |
| Negative Values Allowed?: | Yes | |
PICTUREUsed?: |
No |
FLOAT-LONG~~~~~~~~~~
| Range of Values: | Approximately -1.797693134862316×10^308 to 1.797693134862316×10^308 | |
| Storage Format: | Native IEEE 754 Binary64 Floating-point | |
| Negative Values Allowed?: | Yes | |
PICTUREUsed?: |
No |
FLOAT-SHORT~~~~~~~~~~~
| Range of Values: | Approximately -3.4028235×10^38 to 3.4028235×10^38 | |
| Storage Format: | Native IEEE 754 Binary32 | |
| Negative Values Allowed?: | Yes | |
PICTUREUsed?: |
No |
INDEX~~~~~
| Range of Values: | 0 to maximum address possible (32 or 64 bits) | |
| Storage Format: | Native Binary Integer | |
| Negative Values Allowed?: | No | |
PICTUREUsed?: |
No |
NATIONAL~~~~~~~~
USAGE NATIONAL while syntactically recognized, is not supported by GnuCOBOL |
PACKED-DECIMAL~~~~~~~~~~~~~~
| Range of Values: | Defined by the quantity of9 and the presence or absence of anSin the PICTURE |
|
| Storage Format: | Signed Packed Decimal | |
| Negative Values Allowed?: | IfPICTUREcontainsS
|
|
PICTUREUsed?: |
No |
POINTER~~~~~~~
| Range of Values: | 0 to maximum address possible (32 or 64 bits) | |
| Storage Format: | Native Binary Integer | |
| Negative Values Allowed?: | No | |
PICTUREUsed?: |
No |
PROCEDURE-POINTER~~~~~~~~~~~~~~~~~
Same asPROGRAM-POINTER
|
PROGRAM-POINTER~~~~~~~~~~~~~~~
| Range of Values: | 0 to maximum address possible (32 or 64 bits) | |
| Storage Format: | Native Binary Integer | |
| Negative Values Allowed?: | No | |
PICTUREUsed?: |
No |
SIGNED-INT~~~~~~~~~~
Same asBINARY-LONG SIGNED
|
SIGNED-LONG~~~~~~~~~~~
Same asBINARY-DOUBLE SIGNED
|
SIGNED-SHORT~~~~~~~~~~~~
Same asBINARY-SHORT SIGNED
|
UNSIGNED-INT~~~~~~~~~~~~
Same asBINARY-LONG UNSIGNED
|
UNSIGNED-LONG~~~~~~~~~~~~~
Same asBINARY-DOUBLE UNSIGNED
|
UNSIGNED-SHORT~~~~~~~~~~~~~~
Same asBINARY-SHORT UNSIGNED
|
Big-endian data allocation calls for the bytes that comprise a binary item to be allocated such that the least-significant byte is the right-most byte. For example, a four-byte binary item having a value of decimal 20 would be big-endian allocated as 00000014 (shown in hexadecimal notation).
Little-endian data allocation calls for the bytes that comprise a binary item to be allocated such that the least-significant byte is the left-most byte. For example, a four-byte binary item having a value of decimal 20 would be little-endian allocated as 14000000 (shown in hexadecimal notation).
All CPUs are capable ofunderstandingbig-endian format, which makes it themost-compatibleform of binary storage across computer systems.
Some CPUs such as the Intel/AMD i386/x64 architecture processors used in most Windows PCs prefer to process binary data stored in a little-endian format. Since that format is more efficient on those systems, it is referred to as thenativebinary format.
On a system supporting only one format of binary storage (generally, that would be big-endian), the terms ’most-efficient’ and ’native format’ are synonymous.
UNSIGNED USAGE PACKED-DECIMALUSAGE COMP-3orUSAGE COMP-6 data is stored as a series of bytes such that each byte contains two 4-bit fields, referred to as ’nibbles’ (since they comprise half a "byte", they’re just "nibbles" — don’t groan, I don’t just make this stuff up!). Each nibble represents a9in thePICTUREand each holds a single decimal digit encoded as its binary value (0 = 0000, 1 = 0001, … , 9 = 1001). The last byte of aPACKED-DECIMALorCOMP-3data item will always have its left nibble corresponding to the last9in thePICTUREand its right nibble reserved as a sign indicator. This sign indicator is always present regardless of whether or not thePICTUREincluded anSsymbol.
The first byte of the data item will contain an unused left nibble if thePICTUREhad an even number of9symbols in it.
The sign indicator will have a value of a hexadecimal A through F. Traditional packed decimal encoding rules call for hexadecimal values of F, A, C or E ("FACE") in the sign nibble to indicate a positive value and B or D to represent a negative value (hexadecimal digits 0-9 are undefined). Testing with a Windows MinGW/GnuCOBOL implementation shows that – in fact – hex digit D represents a negative number and any other hexadecimal digit denotes a positive number. Therefore, aPIC S9(3) COMP-3packed-decimal field with a value of -15 would be stored internally as a hexadecimal 015D in GnuCOBOL.
If you attempt to store a negative number into a packed decimal field that has noSin itsPICTURE the absolute value of the negative number will actually be stored.
USAGE COMP-6does not allow for negative values, therefore no sign nibble will be allocated. AUSAGE COMP-6data item containing an odd number of9symbols in itsPICTUREwill leave its leftmost nibble unused.
USAGEspecificationsFLOAT-DECIMAL-16andFLOAT-DECIMAL-34will encode data using IEEE 754Decimal64andDecimal128format, respectively. The former allows for up to 16 digits of exact precision while the latter offers 34. The phrase "exact precision" is used because the traditional binary renderings of decimal real numbers in a floating-point format FLOAT-LONGandFLOAT-SHORT for example) only yield an approximation of the actual value because many decimal fractions cannot be precisely rendered in binary. The Decimal64 and Decimal128 renderings, however, render decimal real numbers in encoded decimal form in much the same way thatPACKED-DECIMALrenders a decimal integer in digit-by-digit decimal form. The exact manner in which this rendering is performed is complex (Wikipedia has an excellent article on the subject just search forDecimal64. FLOAT-DECIMAL-16andFLOAT-DECIMAL-34data items using either Big-Endian or Little-Endian form, whichever is native to the system. USAGEspecificationsFLOAT-LONGandFLOAT-SHORTuse the IEEE 754Binary64andBinary32formats, respectively. These are binary encodings of real decimal numbers, and as such cannot represent every possible value between the minimum and maximum values in the range for those usages. Wikipedia has an excellent article on the Binary64 and Binary32 encoding schemes just search onBinary32orBinary64 GnuCOBOL storesFLOAT-LONGandFLOAT-SHORTdata items using either Big-Endian or Little-Endian form, whichever is native to the system.
USAGEclause specified at the group item level will apply thatUSAGEto all subordinate data items, except those that themselves have aUSAGEclause. USAGEthat is allowed in the report section isUSAGE DISPLAY USING identifier-1 ~~~~~
This clause logically attaches a screen section data item to another data item defined elsewhere in the data division.
ACCEPT FROM(see FROM),TO(see TO),USINGandVALUE(see VALUE) clauses are mutually-exclusive in any screen section data item’s definition. { VALUE IS } {literal-1 [ THRU|THROUGH literal-2 ]}...
{ ~~~~~ } ~~~~ ~~~~~~~
{ VALUES ARE }
~~~~~~
VALUE IS [ ALL ] literal-1 ~~~~~ ~~~
TheVALUEclause is used to define condition names or to assign values (at compilation time) to data items.
AREandISare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. FROM(see FROM),TO(see TO) orUSING(see USING) clause. VALUEclause in the definition of a condition name: VALUE ISandVALUES AREare interchangeable. THRUandTHROUGHare interchangeable. VALUEis used to create condition names. VALUEclause in the definition of any other data item: VALUEspecifies an initial compilation-time value that will be assigned to the storage occupied by the data item in the program object code generated by the compiler. VALUEclause is ignored onEXTERNAL(see EXTERNAL) data items or on any data items defines as subordinate to anEXTERNALdata item. VALUEclause may not be used anywhere in the description of an 01 item (or any of it’s subordinate items) serving as anFDorSDrecord description. ALL PIC X(5) VALUE "A" *> Abbbb PIC X(5) VALUE ALL "A" *> AAAAA PIC 9(3) VALUE 1 *> 001 PIC 9(3) VALUE ALL "1" *> 111
FROM(see FROM),TO(see TO) orUSING(see USING) clause in the same data item’s definition will be ignored. ALLoption is specified, theALLoption will be ignored. INITIALIZE(see INITIALIZE) to initialize all data item occurrences in a table (at run-time) to their data-type-specific default values (numerics: 0, alphabetic and alphanumerics: spaces). VALUEclause on the group item that serves as a parent to the table, as follows: 05 SHIRT-SIZES VALUE "S 14M 15L 16XL17".
10 SHIRT-SIZE-TBL OCCURS 4 TIMES.
15 SST-SIZE PIC X(2).
15 SST-NECK PIC 9(2).
REDEFINES(see REDEFINES) clause: 05 SHIRT-SIZE-VALUES.
10 PIC X(4) VALUE "S 14".
10 PIC X(4) VALUE "M 15".
10 PIC X(4) VALUE "L 16".
10 PIC X(4) VALUEXL17
05 SHIRT-SIZES REDEFINES SHIRT-SIZE-VALUES.
10 SHIRT-SIZE-TBL OCCURS 4 TIMES.
15 SST-SIZE PIC X(2).
15 SST-NECK PIC 9(2).
Admittedly, this table is much more verbose than the one shown with a groupVALUE What is good about this initialization technique, however, is that you can have as manyFILLERandVALUEitems as you need for a larger table, and those values can be as long as necessary!
VALUEandOCCURS(see OCCURS) on the same data item; additionally, they don’t allow aVALUEclause on a data item subordinate to anOCCURS GnuCOBOL, however, has neither of these restrictions! Observe the following example, which illustrates a fourth manner in which tables may be initialized in GnuCOBOL:
05 X OCCURS 6 TIMES.
10 A PIC X(1) VALUE '?'.
10 B PIC X(1) VALUE '%'.
10 N PIC 9(2) VALUE 10.
In this example, all sixAitems will be initialized to "?", all sixBitems will be initialized to "%" and all sixNitems will be initialized to 10. It’s not clear exactly how many times this sort of initialization will be useful, but it’s there if you need it.
FROM(see FROM),TO(see TO),USING(see USING) andVALUEclauses are mutually-exclusive in any screen section data item’s definition. PROCEDURE DIVISION [ { USING Subprogram-Argument... } ]
~~~~~~~~~ ~~~~~~~~ { ~~~~~ }
{ CHAINING Main-Program-Argument...}
~~~~~~~~
[ RETURNING identifier-1 ] .
[ DECLARATIVES. ] ~~~~~~~~~
~~~~~~~~~~~~
[ Event-Handler-Routine... . ]
[ END DECLARATIVES. ]
~~~ ~~~~~~~~~~~~
General-Program-Logic
[ Nested-Subprogram... ]
[ END PROGRAM|FUNCTION name-1 ]
~~~ ~~~~~~~ ~~~~~~~~
The PROCEDURE DIVISION of any GnuCOBOL program marks the point where all executable code is written.
[ BY { REFERENCE [ OPTIONAL ] } ] identifier-1
{ ~~~~~~~~~ ~~~~~~~~ }
{ VALUE [ [ UNSIGNED ] SIZE IS { AUTO } ] }
~~~~~ ~~~~~~~~ ~~~~ { ~~~~ }
{ DEFAULT }
{ ~~~~~~~ }
{ integer-1 }
BYandISare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words have no effect upon the program. USING USINGclause specified on it’s procedure division header. USINGclause must correspond to the order in which those arguments will be passed to the subprogram by the calling program. USINGclause must be defined in the linkage section of the subprogram. No storage is actually allocated for those identifiers in the subprogram as the actual storage for them will exist in the calling program. USAGE BINARY-LONG(see USAGE)) which is the actual argument being passed to the subprogram. In the case of the former, theUSINGclause on the procedure division header should describe the argument via theBY REFERENCE
BY REFERENCEis the assumed default for the firstUSINGargument should noBYclause be specified for it. Subsequent arguments will assume theBYspecification of the argument prior to them should they lack aBYclause of their own. USINGclause will "be visible" to the calling program only ifBY REFERENCEwas explicitly specified or implicitly assumed for the argument on the subprogram’s procedure division header and the argument was passed to the subprogramBY REFERENCEby the calling program. See Subprogram Arguments, for additional information on the mechanics of how arguments are passed to subprograms. SIZEclause allows you to specify the number of bytes aBY VALUEargument will occupy, withSIZE DEFAULTspecifying 4 bytes (this is the default if noSIZEclause is used),SIZE AUTOspecifying the size of the argument in the calling program andSIZE <integer-1>specifying a specific byte count. UNSIGNEDkeyword, legal only ifSIZE AUTOorSIZE <integer-1>are coded, will add the "unsigned" attribute to the argument’s specification in the C-language function header code generated for the subprogram. While not of any benefit when the calling program is a GnuCOBOL program, this can improve compatibility with a C-language calling program. OPTIONAL [ BY REFERENCE ] [ OPTIONAL ] identifier-1
~~~~~~~~~ ~~~~~~~~
PROCEDURE DIVISION CHAININGmay only be coded in a main program (that is, the first program executed when a compiled GnuCOBOL compilation unit is executed). It cannot be used in any form of subprogram. CHAININGclause defines arguments that will be passed to a main program from the operating system. The argument identifiers specified on the CHAINING clause will be populated by character strings comprised of the parameters specified to the program on the command line that executed it, as follows: /usr/local/myprog THIS IS A TEST, there will be five tokens identified by the operating system — "/usr/local/myprog", "THIS", "IS", "A" and "TEST". C:\Pgms\myprog.exe "THIS IS A" TEST — "C:\Pgms\myprog.exe", "THIS IS A" and "TEST". When quote characters are used to create multi-word tokens, the quote characters themselves are stripped from the token’s value. INITIALIZE <identifier-1>(see INITIALIZE) statement were executed. This behaviour when the argument is defined asPIC 9may be unacceptable, as an argument defined asPIC 9(3)but passed in a value of "1" from the command line will receive a value of "100", not "001". Consider defining "numeric" command line arguments asPIC Xand then using theNUMVALintrinsic function (see NUMVAL) function to determine the proper numeric value.
RETURNING identifier-1 ~~~~~~~~~
RETURNINGclause is optional within a subroutine, as not all subroutines return a value to their caller. RETURNINGclause is mandatory within a user-defined function, as all such must return a numeric result. RETURN-CODEspecial register. GLOBAL(see GLOBAL) attribute specified in it’s description in the calling program is automatically visible to and updatable by a subprogram nested with the calling program. See Independent vs Contained vs Nested Subprograms, for more information on subprogram nesting. EXTERNAL(see EXTERNAL) attribute in a subprogram and the calling program (same name in both programs) is automatically visible to and updatable by both programs, even if those programs are compiled separately from one another. The procedure division is the only one of the COBOL divisions that allows you to create your own sections and paragraphs. These are collectively referred to as ’Procedures’ Procedure names are optional in the procedure division and — when used — are named entirely according to the needs and whims of the programmer.
Procedure names may be up to thirty one (31) characters long and may consist of letters, numbers, dashes and underscores. A procedure name may neither begin nor end with a dash (-) or underscore (_) character. This means that "Main", "0100-Read-Transaction" and "17" are all perfectly valid procedure names.
There are three circumstances under which the use of certain GnuCOBOL statements or options will require the specification of procedures. These situations are:
DECLARATIVES(see DECLARATIVES) are specified. ENTRYstatement (see ENTRY) is being used. ALTER <procedure-name>GO TO <procedure-name>MERGE … OUTPUT PROCEDURE <procedure-name>PERFORM <procedure-name>SORT … INPUT PROCEDURE <procedure-name>and/orSORT … INPUT PROCEDURE <procedure-name>
section-name-1 SECTION.
USE { [ GLOBAL ] AFTER STANDARD { EXCEPTION } PROCEDURE ON { INPUT } }
~~~ { ~~~~~~ { ~~~~~~~~~ } { ~~~~~ } }
{ { ERROR } { OUTPUT } }
{ ~~~~~ { ~~~~~~ } }
{ { I-O } }
{ FOR DEBUGGING ON { procedure-name-1 } { ~~~ } }
{ ~~~~~~~~~ { ALL PROCEDURES } { EXTEND } }
{ { ~~~ ~~~~~~~~~~ } { ~~~~~~ } }
{ { REFERENCES OF identifier-1 } { file-name-1 } }
{ }
{ [ GLOBAL ] BEFORE REPORTING identifier-2 }
{ ~~~~~~ ~~~~~~ ~~~~~~~~~ }
{ }
{ AFTER EC|{EXCEPTION CONDITION} }
~~ ~~~~~~~~~ ~~~~~~~~~
TheAFTER EXCEPTION CONDITION
AFTERFORONPROCEDUREandSTANDARDare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. ECandEXCEPTION CONDITIONare interchangeable. USE BEFORE REPORTING SUM(see SUM) orSOURCE(see SOURCE) clauses in the report group. SUPPRESS(see SUPPRESS) statement to squelch the presentation of the specified report group altogether. Note that you will be suppressing this one specific instance of that group’s presentation and not all of them. USE FOR DEBUGGING ALL PROCEDURES. USE FOR DEBUGGINGdeclarative procedure will be ignored at compilation time unlessWITH DEBUGGING MODEis specified in theSOURCE-COMPUTER(see SOURCE-COMPUTER) paragraph. Neither the compiler’s-fdebugging-lineswitch USE FOR DEBUGGINGdeclarative procedures will be ignored at execution time unless the USE FOR DEBUGGINGdeclarative procedure is to display theDEBUG-ITEMspecial register , which will be implicitly and automatically created in your program for you ifWITH DEBUGGING MODEis active. The structure of DEBUG-ITEM will be as follows:
01 DEBUG-ITEM.
05 DEBUG-LINE PIC X(6).
05 FILLER PIC X(1) VALUE SPACE.
05 DEBUG-NAME PIC X(31).
05 FILLER PIC X(1) VALUE SPACE.
05 DEBUG-SUB-1 PIC S9(4) SIGN LEADING SEPARATE.
05 FILLER PIC X(1) VALUE SPACE.
05 DEBUG-SUB-2 PIC S9(4) SIGN LEADING SEPARATE.
05 FILLER PIC X(1) VALUE SPACE.
05 DEBUG-SUB-3 PIC S9(4) SIGN LEADING SEPARATE.
05 FILLER PIC X(1) VALUE SPACE.
05 DEBUG-CONTENTS PIC X(31).
where…
DEBUG-LINE… is the program line number of the statement that triggered the declaratives procedure.
DEBUG-NAME… is the procedure name or identifier name that triggered the declaratives procedure.
DEBUG-SUB-1… is the first subscript value (if any) for the reference of the identifier that triggered the declaratives procedure.
DEBUG-SUB-2… is the second subscript value (if any) for the reference of the identifier that triggered the declaratives procedure.
DEBUG-SUB-3… is the third subscript value (if any) for the reference of the identifier that triggered the declaratives procedure.
DEBUG-CONTENTS… is a (brief) statement of the manner in which the procedure that triggered the declaratives procedure was executed or the first 31 characters of the value of the identifier whose reference triggered the declaratives procedure (the value after the statement was executed).
USE AFTER STANDARD ERROR PROCEDURE GLOBAL(see GLOBAL) option, if used, allows a declarative procedure to be used across the program containing theUSEstatement and any subprograms nested within that program. For example, observe the following data structure which defines a 4 column by 3 row grid of characters:
01 GRID.
05 GRID-ROW OCCURS 3 TIMES.
10 GRID-COLUMN OCCURS 4 TIMES.
15 GRID-CHARACTER PIC X(1).
If the structure contains the following grid of characters:
A B C D E F G H I J K L
ThenGRID-CHARACTER (2, 3)references the "G" andGRID-CHARACTER (3, 2)references the "J".
Subscripts may be specified as numeric (integer) literals, numeric (integer) data items, data items created with any of the picture-less integerUSAGE(see USAGE) specifications,USAGE INDEXdata items or arithmetic expressions resulting in a non-zero integer value.
In the above examples, a comma is used as a separator character between the two subscript values; semicolons ; are also valid subscript separator characters, as are spaces! The use of a comma or semicolon separator in such a situation is technically optional, but by convention most COBOL programmers use one or the other. The use of no separator character (other than a space) is not recommended, even though it is syntactically correct, as this practice can lead to programmer-unfriendly code. It isn’t too difficult to read and understandGRID-CHARACTER(2 3) but it’s another story entirely when trying to comprehendGRID-CHARACTER(I + 1 J / 3)(instead ofGRID-CHARACTER(I + 1, J / 3). The compiler accepts it, but too much of this would make my head hurt.
To see qualification at work, observe the following segments of two data records defined in a COBOL program:
01 EMPLOYEE. 01 CUSTOMER.
05 MAILING-ADDRESS. 05 MAILING-ADDRESS.
10 STREET PIC X(35). 10 STREET PIC X(35).
10 CITY PIC X(15). 10 CITY PIC X(15).
10 STATE PIC X(2). 10 STATE PIC X(2).
10 ZIP-CODE. 10 ZIP-CODE.
15 ZIP-CODE-5 PIC 9(5). 15 ZIP-CODE-5 PIC 9(5).
15 FILLER PIC X(4). 15 FILLER PIC X(4).
Now, let’s deal with the problem of setting the CITY portion of an EMPLOYEEs MAILING-ADDRESS to "Philadelphia". Clearly,MOVE 'Philadelphia' TO CITYcannot work because the compiler will be unable to determine which of the two CITY fields you are referring to.
In an attempt to correct the problem, we could qualify the reference to CITY asMOVE 'Philadelphia' TO CITY OF MAILING-ADDRESS
Unfortunately that too is insufficient because it still insufficiently specifies which CITY is being referenced. To truly identify which specific CITY you want, you’d have to codeMOVE 'Philadelphia' TO CITY OF MAILING-ADDRESS OF EMPLOYEE
Now there can be no confusion as to which CITY is being changed. Fortunately, you don’t need to be quite so specific; COBOL allows intermediate and unnecessary qualification levels to be omitted. This allowsMOVE 'Philadelphia' TO CITY OF EMPLOYEEto do the job nicely.
If you need to qualify a reference to a table, do so by coding something like<identifier-1> OF <identifier-2> ( subscript(s) )
The reserved wordINmay be used in lieu ofOF
identifier-1 [ OF|IN identifier-2 ] [ (subscript...) ] (start:[ length ])
~~ ~~
intrinsic-function-reference (start:[ length ])
The <start> value indicates the starting character position being referenced (character position values start with 1, not 0 as is the case in some programming languages) and <length> specifies how many characters are wanted.
If no <length> is specified, a value equivalent to the remaining character positions from <start> to the end of <identifier-1> or to the end of the value returned by the function will be assumed.
Both <start> and <length> may be specified as integer numeric literals, integer numeric data items or arithmetic expressions with an integer value.
Here are a few examples:
CUSTOMER-LAST-NAME (1:3)References the first three characters of CUSTOMER-LAST-NAME.
CUSTOMER-LAST-NAME (4:)References all character positions of CUSTOMER-LAST-NAME from the fourth onward.
FUNCTION CURRENT-DATE (5:2)References the current month as a 2-digit number in character form. See CURRENT-DATE, for more information.
Hex-Digits (Nibble + 1:1)Assuming that "Nibble" is a numeric data item with a value in the range 0-15, and Hex-Digits is aPIC X(16)item with a value of "0123456789ABCDEF", this converts that numeric value to a hexadecimal digit.
Table-Entry (6) (7:5)References characters 7 through 11 (5 characters in total) in the 6th occurrence of Table-Entry.
Reference modification may be used anywhere an identifier is legal, including serving as the receiving field of statements likeMOVE(see MOVE),STRING(see STRING) andACCEPT(see ACCEPT), to name a few.
Unary-Expression-1 { **|^ } Unary-Expression-2
{ *|/ }
{ +|- }
{ [ +|- ] { ( Arithmetic-Expression-1 ) } }
{ { [ LENGTH OF ] { identifier-1 } } }
{ { ~~~~~~ ~~ { literal-1 } } }
{ { { Function-Reference } } }
{ Arithmetic-Expression-2 }
In complex expressions composed of multiple operators and operands, a precedence of operation applies whereby those operations having a higher precedence are computed first before operations with a lower precedence.
As is the case in almost any other programming language, the programmer is always free to use pairs of parenthesis to enclose sub-expressions of complex expressions that are to be evaluated before other sub-expressions rather than let operator precedence dictate the sequence of evaluation.
In highest to lowest order of precedence, here is a discussion of each category of operation:
+and-with a single argument)The unary "minus" (-) operator returns the arithmetic negation of its single argument, effectively returning as its value the product of its argument and -1.
The unary "plus" (+) operator returns the value of its single argument, effectively returning as its value the product of its argument and +1.
**or^
The value of the left argument is raised to the power indicated by the right argument. Non-integer powers are allowed. The^and**operators are both supported to provide compatibility with programs written for other COBOL implementations.
* and division /
The*operator computes the product of the left and right arguments while the/operator computes the value of the left argument divided by the value of the right argument. If the right argument has a value of zero, expression evaluation will be prematurely terminated before a value is generated. This may cause program failure at run-time.
A sequence of multiple 3rd-level operations A * B / C for example) will evaluate in strict left-to-right sequence if no parenthesis are used to control the order of evaluation.
+ or subtraction +
The+operator calculates the sum of the left and right arguments while the-operator computes the value of the right argument subtracted from that of the left argument.
A sequence of multiple 4th-level operations A - B + C for example) will evaluate in strict left-to-right sequence if no parenthesis are used to control the order of evaluation.
The syntactical rules of COBOL, allowing a dash (-) character in data item names, can lead to some ambiguity.
01 C PIC 9 VALUE 5. 01 D PIC 9 VALUE 2. 01 C-D PIC 9 VALUE 7. 01 I PIC 9 VALUE 0. … COMPUTE I=C-D+1
TheCOMPUTE(see COMPUTE) statement will evaluate the arithmetic expressionC-D+1and then save that result inI
What value will be stored inI The number 4, which is the result of subtracting the value ofD(2) from the value ofC(5) and then adding 1? Or, will it be the number 8, which is the value of adding 1 to the value of data itemC-D(7)?
The right answer is 8 — the value of data itemC-Dplus 1! Hopefully, that was the intended result.
The GnuCOBOL compiler actually went through the following decision-making logic when generating code for theCOMPUTEStatement:
C-Ddefined? If so, use its value for the character sequenceC-D C-Ddata item, then are thereCandDdata items? If not, theCOMPUTEstatement is in error. If there are, however, then code will be generated to subtract the value ofDfromCand add 1 to the result. Had there been at least one space to the left and/or the right of the- there would have been no ambiguity — the compiler would have been forced to use the individualCandDdata items.
To avoid any possible ambiguity, as well as to improve program readability, it’s considered good COBOL programming practice to always code at least one space to both the left and right of every operator in arithmetic expressions as well as the=sign on a COMPUTE.
Here are some examples of how the precedence of operations affects the results of arithmetic expressions (all examples use numeric literals, to simplify the discussion).
| Expression | Result | Notes |
|---|---|---|
| 3 * 4 + 1 | 13 | * has precedence over + |
| 4 * 2 ^ 3 - 10 | 22 | 2^3 is 8 (^ has precedence over *), times 4 is 32, minus 10 is 22. |
| (4 * 2) ^ 3 - 10 | 502 | Parenthesis provide for a recursive application of the arithmetic expression rules, effectively allowing you to alter the precedence of operations. 4 times 2 is 8 (the use of parenthesis "trumps" the exponentiation operator, so the multiplication happens first); 8 ^ 3 is 512, minus 10 is 502. |
| 5 / 2.5 + 7 * 2 - 1.15 | 15.35 | Integer and non-integer operands may be freely intermixed |
Of course, arithmetic expression operands may be numeric data items (any USAGE except POINTER or PROGRAM POINTER) as well as numeric literals.
There are seven types of conditional expressions, as discussed in the following sections.
05 SHIRT-SIZE PIC 99V9.
88 TINY VALUE 0 THRU 12.5
88 XS VALUE 13 THRU 13.5.
88 S VALUE 14, 14.5.
88 M VALUE 15, 15.5.
88 L VALUE 16, 16.5.
88 XL VALUE 17, 17.5.
88 XXL VALUE 18, 18.5.
88 XXXL VALUE 19, 19.5.
88 VERY-LARGE VALUE 20 THRU 99.9.
The condition namesTINYXSSMLXLXXLXXXLandVERY-LARGEwill have TRUE or FALSE values based upon the values within their parent data item (SHIRT-SIZE).
A program wanting to test whether or not the currentSHIRT-SIZEvalue can be classified asXLcould have that decision coded as a combined condition (the most complex type of conditional expression), as either:
IF SHIRT-SIZE = 17 OR SHIRT-SIZE = 17.5 - or - IF SHIRT-SIZE = 17 OR 17.5
Or it could simply utilize the condition name XL as follows:
IF XL
identifier-1 IS [ NOT ] { NUMERIC }
~~~ { ~~~~~~~ }
{ ALPHABETIC }
{ ~~~~~~~~~~ }
{ ALPHABETIC-LOWER }
{ ~~~~~~~~~~~~~~~~ }
{ ALPHABETIC-UPPER }
{ ~~~~~~~~~~~~~~~~ }
{ OMITTED }
{ ~~~~~~~ }
{ class-name-1 }
NUMERIC ALPHABETIC ALPHABETIC-LOWER NOToption reverses the TRUE/FALSE value of the condition. CHARACTER CLASSIFICATIONspecifications in theOBJECT-COMPUTER(see OBJECT-COMPUTER) paragraph. USAGE(see USAGE) is either explicitly or implicitly defined asDISPLAYmay be used inNUMERICor any of theALPHABETICclass conditions. PIC Aitems withNUMERICclass conditions and the use ofPIC 9items withALPHABETICclass conditions. GnuCOBOL has no such restrictions. OMITTED The <class-name-1> option allows you to test for a user-defined class. Here’s an example. First, assume the followingSPECIAL-NAMES(see SPECIAL-NAMES) definition of the user-defined class "Hexadecimal":
SPECIAL-NAMES.
CLASS Hexadecimal IS '0' THRU '9', 'A' THRU 'F', 'a' THRU 'f'.
Now observe the following code, which will execute the150-Process-Hex-Valueprocedure ifEntered-Valuecontains nothing but valid hexadecimal digits:
IF Entered-Value IS Hexadecimal
PERFORM 150-Process-Hex-Value
END-IF
identifier-1 IS [ NOT ] { POSITIVE }
~~~ { ~~~~~~~~ }
{ NEGATIVE }
{ ~~~~~~~~ }
{ ZERO }
~~~~
POSITIVE ZERO NOToption reverses the TRUE/FALSE value of the condition. Here are the relevant sections of code in a program named "testprog", which is designed to simply announce if SWITCH-1 is on:
…
ENVIRONMENT DIVISION.
SPECIAL-NAMES.
SWITCH-1 ON STATUS IS Switch-1-Is-ON.
…
PROCEDURE DIVISION.
…
IF Switch-1-Is-ON
DISPLAY "Switch 1 Is On"
END-IF
…
the following are two different command window sessions — the left on a Unix/Cygwin/OSX system and the right on a windows system — that will set the switch on and then execute the "testprog" program. Notice how the message indicating that the program detected the switch was set is displayed in both examples:
$ COB_SWITCH_1=ON C:>SET COB_SWITCH_1=ON $ export COB_SWITCH_1 C:>testprog $ ./testprog Switch 1 Is On Switch 1 Is On C:> $
{ identifier-1 } IS [ NOT ] RelOp { identifier-2 }
{ literal-1 } ~~~ { literal-2 }
{ arithmetic-expression-1 } { arithmetic-expression-2 }
{ index-name-1 } { index-name-2 }
{ EQUAL TO }
{ ~~~~~ }
{ EQUALS }
{ ~~~~~~ }
{ GREATER THAN }
{ ~~~~~~~ }
{ GREATER THAN OR EQUAL TO }
{ ~~~~~~~ ~~ ~~~~~ }
{ LESS THAN }
{ ~~~~ }
{ LESS THAN OR EQUAL TO }
{ ~~~~ ~~ ~~~~~ }
{ = }
{ > }
{ >= }
{ < }
{ <= }
USAGE(see USAGE) and number of significant digits in either value are irrelevant as the comparison is performed using the actual algebraic values. COLLATING SEQUENCE(as defined inSPECIAL-NAMES(see SPECIAL-NAMES)), not according to the bit-pattern values the characters have in storage. COLLATING SEQUENCEwill, however, be based entirely on the bit-pattern values of the various characters. IS EQUAL TOIS LESS THAN …) versus the symbolic version =< …) of the actual relation operators. [ ( ] Condition-1 [ ) ] { AND } [ ( ] Condition-2 [ ) ]
{ ~~~ }
{ OR }
{ ~~ }
OR AND IF ACCOUNT-STATUS = 1 OR ACCOUNT-STATUS = 2 OR ACCOUNT-STATUS = 7
Could be abbreviated as:
IF ACCOUNT-STATUS = 1 OR 2 OR 7
ANDtake precedence overORin combined conditions. Use parenthesis to change this precedence, if necessary. For example: FALSE AND FALSE OR TRUE AND TRUEEvaluates to TRUE
(FALSE AND FALSE) OR (TRUE AND TRUE)Evaluates to TRUE (since AND has precedence over OR) - this is identical to the previous example
(FALSE AND (FALSE OR TRUE)) AND TRUEEvaluates to FALSE
NOT Condition-1 ~~~
NOToperator has the highest precedence of all logical operators, just as a unary minus sign (which "negates" a numeric value) is the highest precedence arithmetic operator. NOT TRUE AND FALSE AND NOT FALSEEvaluates to FALSE AND FALSE AND TRUE which evaluates to FALSE
NOT (TRUE AND FALSE AND NOT FALSE)Evaluates to NOT (FALSE) which evaluates to TRUE
NOT TRUE AND (FALSE AND NOT FALSE)Evaluates to FALSE AND (FALSE AND TRUE) which evaluates to FALSE
MOVE SPACES TO Employee-Address ADD 1 TO Record-Counter DISPLAY "Record-Counter=" Record-Counter
Some COBOL statements have a "scope of applicability" associated with them where one or more other statements can be considered to be part of or related to the statement in question. An example of such a situation might be the following, where the interest on a loan is being calculated and displayed — 4% interest if the loan balance is under $10000 and 4.5% otherwise (WARNING – the following code has an error!):
IF Loan-Balance < 10000
MULTIPLY Loan-Balance BY 0.04 GIVING Interest
ELSE
MULTIPLY Loan-Balance BY 0.045 GIVING Interest
DISPLAY "Interest Amount = " Interest
In this example, the IF statement actually has a scope that can include two sets of associated statements – one set to be executed when theIF(see IF) condition is TRUE and another if it is FALSE.
Unfortunately, there’s a problem with the above. A human being looking at that code would probably infer that theDISPLAY(see DISPLAY) statement, because of its lack of indentation, is to be executed regardless of the TRUE/FALSE value of theIFcondition. Unfortunately, the GnuCOBOL compiler (or any other COBOL compiler for that matter) won’t see it that way because it really couldn’t care less what sort of indentation, if any, is used. In fact, any COBOL compiler would be just as happy to see the code written like this:
IF Loan-Balance < 10000 MULTIPLY Loan-balance BY 0.04 GIVING Interest ELSE MULTIPLY Loan-Balance BY 0.045 GIVING Interest DISPLAY "Interest Amount = " Interest
So how then do we inform the compiler that theDISPLAYstatement is outside the scope of theIF
That’s where sentences come in.
A COBOL ’Sentence’
IF Loan-Balance < 10000
MULTIPLY Loan-Balance BY 0.04 GIVING Interest
ELSE
MULTIPLY Loan-Balance BY 0.045 GIVING Interest.
DISPLAY "Interest Amount = " Interest
See the period at the end of the secondMULTIPLY(see MULTIPLY)? That is what terminates the scope of theIF thus making theDISPLAYstatement’s execution completely independent of the TRUE/FALSE status of theIF
Unfortunately, this caused some problems. Take a look at this code:
IF A = 1
IF B = 1
DISPLAY "A & B = 1"
ELSE *> This ELSE has a problem!
IF B = 1
DISPLAY "A NOT = 1 BUT B = 1"
ELSE
DISPLAY "NEITHER A NOR B = 1".
The problem with this code is that indentation — so critical to improving the human-readability of a program — can provide an erroneous view of the logical flow. AnELSEis always associated with the most-recently encounteredIF this means the emphasizedELSEwill be associated with theIF B = 1statement, not theIF A = 1statement as the indentation would appear to imply.
This sort of problem led to a band-aid solution — theNEXT SENTENCE
IF A = 1
IF B = 1
DISPLAY "A & B = 1"
ELSE
NEXT SENTENCE
ELSE
IF B = 1
DISPLAY "A NOT = 1 BUT B = 1"
ELSE
DISPLAY "NEITHER A NOR B = 1".
TheNEXT SENTENCEclause informs the compiler that if theB = 1condition is false, control should fall into the first statement that follows the next period.
With the 1985 standard for COBOL, a much more elegant solution was introduced. Any COBOL ’Verb’
IF A = 1
IF B = 1
DISPLAY "A & B = 1"
END-IF
ELSE
IF B = 1
DISPLAY "A NOT = 1 BUT B = 1"
ELSE
DISPLAY "NEITHER A NOR B = 1".
This new facility made the period almost obsolete, as our program segment would probably be coded like this today:
IF A = 1
IF B = 1
DISPLAY "A & B = 1"
END-IF
ELSE
IF B = 1
DISPLAY "A NOT = 1 BUT B = 1"
ELSE
DISPLAY "NEITHER A NOR B = 1"
END-IF
END-IF
COBOL (GnuCOBOL included) still requires that each procedure division paragraph contain at least one sentence if there is any executable code in that paragraph, but a popular coding style is now to simply code a single period right before the end of each paragraph.
The standard for the COBOL language shows the variousEND-verbclauses are optional because using a period as a scope-terminator remains legal.
If you will be porting existing code over to GnuCOBOL, you’ll find it an accommodating facility capable of conforming to whatever language and coding standards that code is likely to use. If you are creating new GnuCOBOL programs, however, I would strongly counsel you to use theEND-verbstructures in those programs.
Not all GnuCOBOL implementations support file sharing and record-locking options. Whether they do or not depends upon the operating system they were built for and the build options that were used when the specific GnuCOBOL implementation was generated.
Any limitations imposed on a successfulOPEN(see OPEN) will remain in place until your program either issues aCLOSE(see CLOSE) against the file or the program terminates.
File sharing is controlled through the use of aSHARING
SHARING WITH { ALL OTHER }
~~~~~~~ { ~~~ }
{ NO OTHER }
{ ~~ }
{ READ ONLY }
~~~~ ~~~~
This clause may be used either in the file’sSELECTstatement (see SELECT), on theOPENstatement (see OPEN) which initiates your program’s use of the file, or both. If aSHARINGoption is specified in both places, the specifications made on theOPENstatement will take precedence over those from theSELECTstatement.
Here are the meanings of the three options:
ALL OTHER When your program opens a file with this sharing option in effect, no restrictions will be placed on other programs attempting toOPENthe file after your program did. This is the default sharing mode.
NO OTHER When your program opens a file with this sharing option in effect, your program announces that it is unwilling to allow any other program to have any access to the file as long as you are using that file;OPENattempts made in other programs will fail with a file status of 37 ("PERMISSION DENIED") until such time as youCLOSE(see CLOSE) the file.
READ ONLY Opening a file with this sharing option indicates you are willing to allow other programs toOPENthe file for input while you have it open. If they attempt any otherOPEN theirs will fail with a file status of 37. Of course, your program may fail if someone else got to the file first and opened it with a sharing option that imposed file-sharing limitations.
If theSELECTof a file is coded with aFILE STATUSclause,OPENfailures — including those induced by sharing failures — will be detectable by the program and a graceful recovery (or at least a graceful termination) will be possible. If no such clause was coded, however, a runtime message will be issued and the program will be terminated.
The various I/O statements your program can execute are capable of imposing limitations on access by other concurrently-executing programs to the file record they just accessed. These limitations are syntactically imposed by placing a lock on the record using aLOCKclause. Other records in the file remain available, assuming that file-sharing limitations imposed at the time the file was opened didn’t prevent access to the entire file.
SELECT(see SELECT) statement or fileOPEN(see OPEN) specifiesSHARING WITH NO OTHER record locking will be disabled. SELECTcontains aLOCK MODE IS AUTOMATIC SELECTcontains aLOCK MODE IS MANUAL LOCK ONclause is specified in the file’sSELECT locks (either automatically or manually acquired) will continue to accumulate as more and more records are read, until they are explicitly released. This is referred to as ’multiple record locking’ Locks acquired vie multiple record locking remain in-effect until the program holding the lock…
LOCK ON LOCKclause, which may be coded on aREAD(see READ),REWRITE(see REWRITE) orWRITEstatement (see WRITE) looks like this: { IGNORING LOCK }
{ ~~~~~~~~ ~~~~ }
{ WITH [ NO ] LOCK }
{ ~~ ~~~~ }
{ WITH KEPT LOCK }
{ ~~~~ ~~~~ }
{ WITH IGNORE LOCK }
{ ~~~~~~ ~~~~ }
{ WITH WAIT }
~~~~
TheWITH [ NO ] LOCKoption is the only one available toREWRITEorWRITEstatements.
The meanings of the various record locking options are as follows:
IGNORING LOCK WITH IGNORE LOCK These options (which are synonymous) inform GnuCOBOL that any locks held by other programs should be ignored.
WITH LOCK Access to the record by other programs will be denied.
WITH NO LOCK The record will not be locked. This is the default locking option in effect for all statements.
WITH KEPT LOCK When single record locking is in-effect, as a new record is accessed, locks held for previous records are released. By using this option, not only is the newly-accessed record locked (as WITH LOCK would do), but prior record locks will be retained as well. A subsequentREADwithout theKEPT LOCKoption will release all "kept" locks, as will theUNLOCKstatement.
WITH WAIT This option informs GnuCOBOL that the program is willing to wait for a lock held (by another program) on the record being read to be released.
Without this option, an attempt to read a locked record will be immediately aborted and a file status of 51 will be returned.
With this option, the program will wait for a pre-configured time for the lock to be released. If the lock is released within the preconfigured wait time, the read will be successful. If the pre-configured wait time expires before the lock is released, the read attempt will be aborted and a 51 file status will be issued.
[ AT END imperative-statement-1 ]
~~~
[ NOT AT END imperative-statement-2 ]
~~~ ~~~
READ(see READ) andRETURN(see RETURN) statements: AT ENDclause will — if present — cause <imperative-statement-1> (see Imperative Statement) to be executed if the statement fails due to a file status of 10 (end-of-file). See File Status Codes, for a list of possible File Status codes. AnAT ENDclause will not detect other non-zero file-status values.
Use aDECLARATIVES(see DECLARATIVES) routine or an explicitly-declared file status field tested after theREADorRETURNto detect error conditions other than end-of-file.
NOT AT ENDclause will cause <imperative-statement-2> to be executed if theREADorRETURNattempt is successful. SEARCH(see SEARCH) andSEARCH ALL(see SEARCH ALL) statements: AT ENDclause detects and handles the case where either form of table search has failed to locate an entry that satisfies the search conditions being used. NOT AT ENDclause is not allowed on either form of table search. ADD CORRESPONDING group-item-1 TO group-item-2 MOVE CORRESPONDING group-item-1 TO group-item-2 SUBTRACT CORRESPONDING group-item-1 FROM group-item-2
This option allows one or more data items within one group item (<group-item-1> — the first named on the statement) to be paired with correspondingly-named (hence the name) in a second group item (<group-item-2> — the second named on the statement). The contents of <group-item-1> will remain unaffected by the statement while one or more data items within <group-item-2> will be changed.
In order for <data-item-1>, defined subordinate to group item <group-item-1> to be a "corresponding" match to <data-item-2> which is subordinate to <group-item-2>, each of the following must be true:
FILLER FILLER names. MOVEverb… ADDorSUBTRACTverbs, both <data-item-1> and <data-item-2> must be numeric, elementary, unedited items. REDEFINES(see REDEFINES) orRENAMES(see RENAMES) of another data item. OCCURS(see OCCURS) clause, although either may contain subordinate data items that do have anOCCURSclause (assuming rule 3a applies) Observe the definitions of data items "Q" and "Y"…
01 Q. 01 Y.
03 X. 02 A PIC X(1).
05 A PIC 9(1). 02 G1.
05 G1. 03 G2.
10 G2. 04 B PIC X(1).
15 B PIC X(1). 02 C PIC X(1).
05 C. 02 G3.
10 FILLER PIC X(1). 03 G5.
05 G3. 04 D PIC X(1).
10 G4. 03 G6 PIC X(1).
15 D PIC X(1). 02 E PIC 9(1).
05 E PIC X(1). 02 F PIC X(1).
05 F REDEFINES V1 02 G PIC X(4).
PIC X(1). 02 H OCCURS 4 TIMES
05 G. PIC X(1).
10 G6 OCCURS 4 TIMES 66 I RENAMES E.
PIC X(1). 02 J.
05 H PIC X(4). 03 K.
05 I PIC 9(1). 04 L.
05 J. 05 M.
10 K.
15 M PIC X(1).
The following are the valid CORRESPONDING matches, assuming the statementMOVE CORRESPONDING X TO Yis being executed (there are no valid corresponding matches forADD CORRESPONDINGorSUBTRACT CORRESPONDINGbecause every potential match up violates rule #4):
The following are the CORRESPONDING match ups that passed rule #1 (but failed on another rule), and the reasons why they failed.
| Data Item | Failure Reason |
|---|---|
D |
Fails due to rule #2b |
E |
Fails due to rule #3b |
F |
Fails due to rule #5 |
G1 |
Fails due to rule #3a |
G2 |
Fails due to rule #3a |
G3 |
Fails due to rule #3a |
G4 |
Fails due to rule #1 |
G5 |
Fails due to rule #1 |
G6 |
Fails due to rule #6 |
H |
Fails due to rule #6 |
I |
Fails due to rule #5 |
J |
Fails due to rule #3a |
K |
Fails due to rule #3a |
L |
Fails due to rule #1 |
M |
Fails due to rule #2a |
[ INVALID KEY imperative-statement-1 ] ~~~~~~~ [ NOT INVALID KEY imperative-statement-2 ] ~~~ ~~~~~~~
Specification of anINVALID KEYclause will allow your program to trap an I/O failure condition (with an I/O error code in the file’sFILE-STATUS(see SELECT) field) that has occurred due to a record-not-found condition and handle it gracefully by executing <imperative-statement-1> (see Imperative Statement).
An optionalNOT INVALID KEY
[ ON EXCEPTION imperative-statement-1 ]
~~~~~~~~~
[ NOT ON EXCEPTION imperative-statement-2 ]
~~~ ~~~~~~~~~
Specification of an exception clause will allow your program to trap a failure condition that has occurred and handle it gracefully by executing <imperative-statement-1> (see Imperative Statement). If such a condition occurs at runtime without having one of these clauses specified, an error message will be generated (by the GnuCOBOL runtime library) to the SYSERR device (pipe 2). The program may also be terminated, depending upon the type and severity of the error.
An optionalNOT ON EXCEPTION
[ ON OVERFLOW imperative-statement-1 ]
~~~~~~~~
[ NOT ON OVERFLOW imperative-statement-2 ]
~~~ ~~~~~~~~
AnON OVERFLOWclause will allow your program to trap a failure condition that has occurred and handle it gracefully by executing <imperative-statement-1> (see Imperative Statement). If such a condition occurs at runtime without having one of these clauses specified, an error message will be generated (by the GnuCOBOL runtime library) to the SYSERR device (pipe 2). The program may also be terminated, depending upon the type and severity of the error.
An optionalNOT ON OVERFLOW
[ ON SIZE ERROR imperative-statement-1 ]
~~~~ ~~~~~
[ NOT ON SIZE ERROR imperative-statement-2 ]
~~~ ~~~~ ~~~~~
Including anON SIZE ERRORclause on an arithmetic statement will allow your program to trap a failure of an arithmetic statement (either generating a result too large for the receiving field, or attempting to divide by zero) and handle it gracefully by executing <imperative-statement-1> (see Imperative Statement). Field size overflow conditions occur silently, usually without any runtime messages being generated, even though such events rarely lend themselves to generating correct results. Division by zero errors, when noON SIZE ERRORclause exists, will produce an error message (by the GnuCOBOL runtime library) to the SYSERR device (pipe 2) and will also abort the program.
An optionalNOT ON SIZE ERROR
ROUNDED [ MODE IS { AWAY-FROM-ZERO }
~~~~~~~ ~~~~ { ~~~~~~~~~~~~~~ }
{ NEAREST-AWAY-FROM-ZERO }
{ ~~~~~~~~~~~~~~~~~~~~~~ }
{ NEAREST-EVEN }
{ ~~~~~~~~~~~~ }
{ NEAREST-TOWARD-ZERO }
{ ~~~~~~~~~~~~~~~~~~~ }
{ PROHIBITED }
{ ~~~~~~~~~~ }
{ TOWARD-GREATER }
{ ~~~~~~~~~~~~~~ }
{ TOWARD-LESSER }
{ ~~~~~~~~~~~~~ }
{ TRUNCATION }
~~~~~~~~~~
The following rules apply to the rounding behaviour induced by this clause.
ROUNDEDclause is a non-integer value. ROUNDEDclause is the same as specifyingROUNDED MODE IS TRUNCATION ROUNDEDclause without aMODEspecification is the same as specifyingROUNDED MODE IS NEAREST-AWAY-FROM-ZERO The behaviour of the eight different rounding modes is defined in the following table. Note that a "…" indicates the last digit repeats. The examples assume an integer receiving field.
AWAY-FROM-ZERORounding is to the nearest value of larger magnitude.
| -3.510 ⇒ -4 | +3.510 ⇒ +4 |
| -3.500 ⇒ -4 | +3.500 ⇒ +4 |
| -3.499… ⇒ -4 | +3.499… ⇒ +4 |
| -2.500 ⇒ -3 | +2.500 ⇒ +3 |
| -2.499… ⇒ -3 | +2.499… ⇒ +3 |
NEAREST-AWAY-FROM-ZERORounding is to the nearest value (larger or smaller). If two values are equally near, the value with the larger absolute value is selected.
| -3.510 ⇒ -4 | +3.510 ⇒ +4 |
| -3.500 ⇒ -4 | +3.500 ⇒ +4 |
| -3.499… ⇒ -3 | +3.499… ⇒ +3 |
| -2.500 ⇒ -3 | +2.500 ⇒ +3 |
| -2.499… ⇒ -2 | +2.499… ⇒ +2 |
NEAREST-EVENRounding is to the nearest value (larger or smaller). If two values are equally near, the value whose rightmost digit is even is selected. This mode is sometimes called "Banker’s rounding".
| -3.510 ⇒ -4 | +3.510 ⇒ +4 |
| -3.500 ⇒ -4 | +3.500 ⇒ +4 |
| -3.499… ⇒ -3 | +3.499… ⇒ +3 |
| -2.500 ⇒ -2 | +2.500 ⇒ +2 |
| -2.499… ⇒ -2 | +2.499… ⇒ +2 |
NEAREST-TOWARD-ZERORounding is to the nearest value (larger or smaller). If two values are equally near, the value with the smaller absolute value is selected.
| -3.510 ⇒ -4 | +3.510 ⇒ +4 |
| -3.500 ⇒ -3 | +3.500 ⇒ +3 |
| -3.499… ⇒ -3 | +3.499… ⇒ +3 |
| -2.500 ⇒ -2 | +2.500 ⇒ +2 |
| -2.499… ⇒ -2 | +2.499… ⇒ +2 |
PROHIBITEDNo rounding is performed. If the value cannot be represented exactly in the desired format, the EC-SIZE-TRUNCATION condition (exception code 1005) is set (and may be retrieved via theACCEPT(see ACCEPT FROM Runtime-Info) statement) and the results of the operation are undefined.
| -3.510 ⇒ Undefined | +3.510 ⇒ Undefined |
| -3.500 ⇒ Undefined | +3.500 ⇒ Undefined |
| -3.499… ⇒ Undefined | +3.499… ⇒ Undefined |
| -2.500 ⇒ Undefined | +2.500 ⇒ Undefined |
| -2.499… ⇒ Undefined | +2.499… ⇒ Undefined |
TOWARD-GREATERRounding is toward the nearest value whose algebraic value is larger.
| -3.510 ⇒ -3 | +3.510 ⇒ +4 |
| -3.500 ⇒ -3 | +3.500 ⇒ +4 |
| -3.499… ⇒ -3 | +3.499… ⇒ +4 |
| -2.500 ⇒ -2 | +2.500 ⇒ +3 |
| -2.499… ⇒ -2 | +2.499… ⇒ +3 |
TOWARD-LESSERRounding is toward the nearest value whose algebraic value is smaller.
| -3.510 ⇒ -4 | +3.510 ⇒ +3 |
| -3.500 ⇒ -4 | +3.500 ⇒ +3 |
| -3.499… ⇒ -4 | +3.499… ⇒ +3 |
| -2.500 ⇒ -3 | +2.500 ⇒ +2 |
| -2.499… ⇒ -3 | +2.499… ⇒ +2 |
TRUNCATIONRounding is to the nearest value whose magnitude is smaller.
| -3.510 ⇒ -3 | +3.510 ⇒ +3 |
| -3.500 ⇒ -3 | +3.500 ⇒ +3 |
| -3.499… ⇒ -3 | +3.499… ⇒ +3 |
| -2.500 ⇒ -2 | +2.500 ⇒ +2 |
| -2.499… ⇒ -2 | +2.499… ⇒ +2 |
COB-CRT-STATUSPIC 9(4) — This is the default data item allocated for use by theACCEPT <screen-data-item>statement (see ACCEPT screen-data-item), if noCRT STATUS(see SPECIAL-NAMES) clause was specified..
DEBUG-ITEMGroup Item — A group item in which debugging information generated by aUSE FOR DEBUGGINGsection in the declaratives area of the procedure division will place information documenting why theUSE FOR DEBUGGINGprocedure was invoked. Consult theDECLARATIVES(see DECLARATIVES) documentation for information on the structure of this register.
LINAGE-COUNTERBINARY-LONG SIGNED — An occurrence of this register exists for each selected file having aLINAGE(see File/Sort-Description) clause. If there are multiple files whose file descriptions haveLINAGEclauses, any explicit references to this register will require qualification (usingOF file-name. The value of this register will be the current logical line number within the page body. The value of this register cannot be modified.
LINE-COUNTERBINARY-LONG SIGNED — An occurrence of this register exists for each report defined in the program (via anRD(see REPORT SECTION)). If there are multiple reports, any explicit references to this register not made in the report section will require qualification OF report-name. The value of this register will be the current logical line number on the current page. The value of this register cannot be modified.
NUMBER-OF-CALL-PARAMETERSBINARY-LONG SIGNED — This register contains the number of arguments passed to a subroutine — the same value that would be returned by theC$NARGbuilt-in system subroutine (see C$NARG). Its value will be zero when referenced in a main program. This register, when referenced from within a user-defined function, returns a value of one (1) if the function has any number of arguments and a zero if it has no arguments.
PAGE-COUNTERBINARY-LONG SIGNED — An occurrence of this register exists for each report having anRD(see REPORT SECTION). If there are multiple such reports, any explicit references to this register not made in the report section will require qualification (OF report-name. The value of this register will be the current report page number. The value of this register cannot be modified.
RETURN-CODEBINARY-LONG SIGNED — This register provides a numeric data item into which a subroutine mayMOVE(see MOVE) a value (which will then be available to the calling program) prior to transferring control back to the program that called it, or into which a main program mayMOVEa value before returning control to the operating system. Many built-in subroutines will return a value using this register. These values are — by convention — used to signify success (usually with a value of 0) or failure (usually with a non-zero value) of the process the program was attempting to perform. This register may also be modified by a subprogram as a result of that subprogram’s use of theRETURNING(see PROCEDURE DIVISION RETURNING) clause.
SORT-RETURNBINARY-LONG SIGNED — This register is used to report the success/fail status of aRELEASE(see RELEASE) orRETURN(see RETURN) statement. A value of 0 is reported on success. A value of 16 denotes failure. AnAT END(see AT END + NOT AT END) condition on aRETURNis not considered a failure.
WHEN-COMPILEDPIC X(16) — This register contains the date and time the program was compiled in the format "mm/dd/yyhh.mm.ss". Note that only a two-digit year is provided.
MOVE FUNCTION LENGTH(Employee-Last-Name) TO Employee-LN-Len
Note how the wordFUNCTIONis part of the syntax when you use an intrinsic function. You can use intrinsic functions without having to include the reserved wordFUNCTIONvia settings in theREPOSITORY(see REPOSITORY) paragraph. You may accomplish the same thing by specifying the-fintrinsicsswitch
User-written functions (see Subprogram Types) never require theFUNCTIONkeyword when they are executed, because each user-written function a program uses must be included in that program’sREPOSITORYparagraph, which therefore makes theFUNCTIONkeyword optional.
The following intrinsic functions, known to other "dialects" of COBOL, are defined to GnuCOBOL as reserved words but are not otherwise implemented currently. Any attempts to use these functions will result in a compile-time error message.
BOOLEAN-OF-INTEGER FORMATTED-CURRENT-DATE INTEGER-OF-FORMATTED-DATE CHAR-NATIONAL FORMATTED-DATE NATIONAL-OF DISPLAY-OF FORMATTED-DATETIME STANDARD-COMPARE EXCEPTION-FILE-N FORMATTED-TIME TEST-FORMATTED-DATETIME EXCEPTION-LOCATION-N INTEGER-OF-BOOLEAN
The supported intrinsic functions are listed in the following sections, along with their syntax and usage notes.
ABS(number) ~~~
ACOS(cosine) ~~~~
The result will be an angle, expressed in radians. You may convert this to an angle measured in degrees, as follows:
COMPUTE <degrees> = ( <radians> * 180 ) / FUNCTION PIANNUITY(interest-rate, number-of-periods) ~~~~~~~
The <interest-rate> is the rate of interest paid at each payment. If you only have an annual interest rate and you wish to compute monthly annuity payments, divide the annual interest rate by 12 and use that value for <interest-rate> on this function.
Multiply the result of this function times the desired principal amount to determine the amount of each period’s payment.
A note for the financially challenged: an annuity is basically a reverse loan; an accountant would take the result of this function multiplied by -1 times the principal amount to compute a loan payment you are making.
ASIN(sine) ~~~~
The result will be an angle, expressed in radians. You may convert this to an angle measured in degrees, as follows:
COMPUTE <degrees> = ( <radians> * 180 ) / FUNCTION PIATAN(tangent) ~~~~
The result will be an angle, expressed in radians. You may convert this to an angle measured in degrees, as follows:
COMPUTE <degrees> = ( <radians> * 180 ) / FUNCTION PIBYTE-LENGTH(string) ~~~~~~~~~~~
For example, if <string> is encoded using a double-byte character set such as UNICODE (where each character is represented by 16 bits of storage, not the 8-bits inherent to character sets like ASCII or EBCDIC), then calling this function with a <string> argument whosePICTURE(see PICTURE) isX(4)would return a value of 8 rather than the value 4.
Contrast this with theLENGTH(see LENGTH) function.
CHAR(integer) ~~~~
For example, if the program is using the (default) ASCII character set, CHAR(34) returns the 34th character in the ASCII character set — an exclamation-point ("!"). If you are using this function to convert a numeric value to its corresponding ASCII character, you must use an argument value one greater than the numeric value.
If an argument whose value is less than 1 or greater than 256 is specified, the character in the program collating sequence corresponding to a value of all zero bits is returned.
The following code is an alternative approach when you just wish to convert a number to its ASCII equivalent:
01 Char-Value.
05 Numeric-Value USAGE BINARY-CHAR.
…
MOVE numeric-character-value TO Numeric-Value
TheChar-Valueitem now has the corresponding ASCII character value.
COMBINED-DATETIME(days, seconds) ~~~~~~~~~~~~~~~~~
If a <days> value less than 1 or greater than 3067671 is specified, or if a <seconds> value less than 1 or greater than 86400 is specified, a value of 0 is returned and a runtime error will result.
CONCATENATE(string-1 [, string-2 ]...) ~~~~~~~~~~~
If a numeric literal orPIC 9identifier is specified as an argument, decimal points, if any, will be removed and negative signs inPIC S9fields or numeric literals will be inserted as defined by theSIGN IS(see SIGN IS) clause (or absence thereof) of the field. Numeric literals are processed as ifSIGN IS TRAILING SEPARATEwere in effect.
COS(angle) ~~~
The <angle> is assumed to be a value expressed in radians. If you need to determine the cosine of an angle measured in degrees, you first need to convert that angle to radians as follows:
COMPUTE <radians> = ( <degrees> * FUNCTION PI) / 180CURRENCY-SYMBOL ~~~~~~~~~~~~~~~
Changing the currency symbol via theSPECIAL-NAMES(see SPECIAL-NAMES) paragraph’sCURRENCY SYMBOLsetting will not affect the value returned by this function.
CURRENT-DATE ~~~~~~~~~~~~
01 CURRENT-DATE-AND-TIME.
05 CDT-Year PIC 9(4).
05 CDT-Month PIC 9(2). *> 01-12
05 CDT-Day PIC 9(2). *> 01-31
05 CDT-Hour PIC 9(2). *> 00-23
05 CDT-Minutes PIC 9(2). *> 00-59
05 CDT-Seconds PIC 9(2). *> 00-59
05 CDT-Hundredths-Of-Secs PIC 9(2). *> 00-99
05 CDT-GMT-Diff-Hours PIC S9(2)
SIGN LEADING SEPARATE.
05 CDT-GMT-Diff-Minutes PIC 9(2). *> 00 or 30
Since this function has no arguments, no parenthesis should be specified.
DATE-OF-INTEGER(integer) ~~~~~~~~~~~~~~~
A value less than 1 or greater than 3067671 (9999/12/31) will return a result of 0.
DATE-TO-YYYYMMDD(yymmdd [, yy-cutoff ]) ~~~~~~~~~~~~~~~~
The optional <yy-cutoff> (a numeric integer data item or literal) argument is the year cutoff used to delineate centuries; if the year component of the date meets or exceeds this cutoff value, the result will be 19yymmdd; if the year component of the date is less than the cutoff value, the result will be 20yymmdd. The default cutoff value if no second argument is given will be 50.
DAY-OF-INTEGER(integer) ~~~~~~~~~~~~~~
A value less than 1 or greater than 3067671 (9999/12/31) will return a result of 0.
DAY-TO-YYYYDDD(yyddd [, yy-cutoff]) ~~~~~~~~~~~~~~
The optional <yy-cutoff> argument (a numeric integer data item or literal) is the year cutoff used to delineate centuries; if the year component of the date meets or exceeds this cutoff value, the result will be 19yyddd; if the year component of the date is less than the cutoff, the result will be 20yyddd. The default cutoff value if no second argument is given will be 50.
E ~
Since this function has no arguments, no parenthesis should be specified.
EXCEPTION-FILE ~~~~~~~~~~~~~~
The name returned after the file status information will be returned only if the returned file status value is not 00.
Since this function has no arguments, no parenthesis should be specified.
The documentation of theCBL_ERROR_PROCbuilt-in system subroutine (see CBL_ERROR_PROC) built-in subroutine illustrates the use of this function.
EXCEPTION-LOCATION ~~~~~~~~~~~~~~~~~~
Since this function has no arguments, no parenthesis should be specified.
The program must be compiled with the-debugswitch
The documentation of theCBL_ERROR_PROCbuilt-in system subroutine (see CBL_ERROR_PROC) built-in subroutine illustrates the use of this function.
EXCEPTION-STATEMENT ~~~~~~~~~~~~~~~~~~~
Since this function has no arguments, no parenthesis should be specified.
The program must be compiled with the-debugswitch
The documentation of theCBL_ERROR_PROCbuilt-in system subroutine (see CBL_ERROR_PROC) built-in subroutine illustrates the use of this function.
EXCEPTION-STATUS ~~~~~~~~~~~~~~~~
Since this function has no arguments, no parenthesis should be specified.
The documentation of theCBL_ERROR_PROCbuilt-in system subroutine (see CBL_ERROR_PROC) built-in subroutine illustrates the use of this function.
The following are the error type strings, and their corresponding exception codes and descriptions.
| Code | Error Type | Description |
|---|---|---|
| 0101 | EC-ARGUMENT-FUNCTION | Function argument error |
| 0202 | EC-BOUND-ODO | OCCURS … DEPENDING ON data item out of bounds |
| 0204 | EC-BOUND-PTR | Data-pointer contains an address that is out of bounds |
| 0205 | EC-BOUND-REF-MOD | Reference modifier out of bounds |
| 0207 | EC-BOUND-SUBSCRIPT | Subscript out of bounds |
| 0303 | EC-DATA-INCOMPATIBLE | Incompatible data exception |
| 0500 | EC-I-O | input-output exception |
| 0501 | EC-I-O-AT-END | I-O status "1x" |
| 0502 | EC-I-O-EOP | An end of page condition occurred |
| 0504 | EC-I-O-FILE-SHARING | I-O status "6x" |
| 0505 | EC-I-O-IMP | I-O status "9x" |
| 0506 | EC-I-O-INVALID-KEY | I-O status "2x" |
| 0508 | EC-I-O-LOGIC-ERROR | I-O status "4x" |
| 0509 | EC-I-O-PERMANENT-ERROR | I-O status "3x" |
| 050A | EC-I-O-RECORD-OPERATION | I-O status "5x" |
| 0601 | EC-IMP-ACCEPT | Implementation-defined accept condition |
| 0602 | EC-IMP-DISPLAY | Implementation-defined display condition |
| 0A00 | EC-OVERFLOW | Overflow condition |
| 0A02 | EC-OVERFLOW-STRING | STRING overflow condition |
| 0A03 | EC-OVERFLOW-UNSTRING | UNSTRING overflow condition |
| 0B05 | EC-PROGRAM-NOT-FOUND | Called program not found |
| 0D03 | EC-RANGE-INSPECT-SIZE | Size of replace item in inspect differs |
| 1000 | EC-SIZE | Size error exception |
| 1004 | EC-SIZE-OVERFLOW | Arithmetic overflow in calculation |
| 1005 | EC-SIZE-TRUNCATION | Significant digits truncated in store |
| 1007 | EC-SIZE-ZERO-DIVIDE | Division by zero |
| 1202 | EC-STORAGE-NOT-ALLOC | The data-pointer specified in a FREE statement does not identify currently allocated storage |
| 1203 | EC-STORAGE-NOT-AVAIL | The amount of storage requested by an ALLOCATE statement is not available |
EXP(number) ~~~
EXP10(number) ~~~~~
FACTORIAL(number) ~~~~~~~~~
FRACTION-PART(number) ~~~~~~~~~~~~~
<number> -- FUNCTION INTEGER-PART(<number>) HIGHEST-ALGEBRAIC(numeric-identifier) ~~~~~~~~~~~~~~~~~
INTEGER(number) ~~~~~~~
INTEGER-OF-DATE(date) ~~~~~~~~~~~~~~~
Once in that form, mathematical operations may be performed against the internal date before it is transformed back into a date using theDATE-OF-INTEGER(see DATE-OF-INTEGER) orDAY-OF-INTEGER(see DAY-OF-INTEGER) function.
INTEGER-OF-DAY(date) ~~~~~~~~~~~~~~
Once in that form, mathematical operations may be performed against the internal date before it is transformed back into a date using theDATE-OF-INTEGER(see DATE-OF-INTEGER) orDAY-OF-INTEGER(see DAY-OF-INTEGER) function.
INTEGER-PART(number) ~~~~~~~~~~~~
LENGTH(string) ~~~~~~
The value returned by this function is not the number of bytes of storage occupied by string, but rather the number of actual characters making up the string. For example, if <string> is encoded using a double-byte character set such as UNICODE (where each character is represented by 16 bits of storage, not the 8-bits inherent to character sets like ASCII or EBCDIC), then calling this function with a <string> argument whosePICTURE is X(4)would return a value of 4 rather than the value 8 (the actual number of bytes of storage occupied by that item).
Contrast this function with theBYTE-LENGTH(see BYTE-LENGTH) andLENGTH-AN(see LENGTH-AN) functions.
LENGTH-AN(string) ~~~~~~~~~
This intrinsic function is identical to theBYTE-LENGTH(see BYTE-LENGTH) function.
Note that the value returned by this function is not the number of characters making up the <string>, but rather the number of actual bytes of storage required to store <string>. For example, if <string> is encoded using a double-byte character set such as UNICODE (where each character is represented by 16 bits of storage, not the 8-bits inherent to character sets like ASCII or EBCDIC), then calling this function with a <string> argument whosePICTURE is X(4)would return a value of 8 rather than the value 4.
Contrast this with theLENGTH(see LENGTH) function.
LOCALE-COMPARE(argument-1, argument-2 [ , locale ]) ~~~~~~~~~~~~~~
Either or both of the 1st two arguments may be an alphanumeric literal, a group item or an elementary item appropriate to storing alphabetic or alphanumeric data. If the lengths of the two arguments are unequal, the shorter will be assumed to be padded to the right with spaces.
The two arguments will be compared, character by character, against each other until their relationship to each other can be determined. The comparison is made according to the cultural rules in effect for the specified <locale> name or for the current locale if no <locale> argument is specified. Once that relationship is determined, a one-character alphanumeric value will be returned as follows:
See LOCALE Names, for a list of typically-available locale names.
LOCALE-DATE(date [, locale ]) ~~~~~~~~~~~
You may include an optional second argument to specify the <locale> name (group item orPIC Xidentifier) you’d like to use for date formatting. If used, this second argument must be an identifier. Locale names are specified using UNIX-standard names.
LOCALE-TIME(time [, locale ]) ~~~~~~~~~~~
You may include an optional <locale> name (a group item orPIC Xidentifier) you’d like to use for time formatting. If used, this second argument must be an identifier. Locale names are specified using UNIX-standard names.
LOCALE-TIME-FROM-SECONDS(seconds [, locale ]) ~~~~~~~~~~~~~~~~~~~~~~~~
You may include an optional <locale> name (a group item orPIC Xidentifier) you’d like to use for time formatting. If used, this second argument must be an identifier. Locale names are specified using UNIX-standard names.
See LOCALE Names, for a list of typically-available locale names.
LOG(number) ~~~
LOG10(number) ~~~~~
LOWER-CASE(string) ~~~~~~~~~~
What constitutes a "letter" (or upper/lower case too, for that manner) may be influenced through the use of aCHARACTER CLASSIFICATION(see OBJECT-COMPUTER).
LOWEST-ALGEBRAIC(numeric-identifier) ~~~~~~~~~~~~~~~~
MAX(number-1 [, number-2 ]...) ~~~
MEAN(number-1 [, number-2 ]...) ~~~~
MEDIAN(number-1 [, number-2 ]...) ~~~~~~
MIDRANGE(number-1 [, number-2 ]...) ~~~~~~~~
MIN(number-1 [, number-2 ]...) ~~~
MOD(value, modulus) ~~~
MODULE-CALLER-ID ~~~~~~~~~~~~~~~~
The discussion of theMODULE-TIME(see MODULE-TIME) function includes a sample program that uses this function.
Since this function has no arguments, no parenthesis should be specified.
MODULE-DATE ~~~~~~~~~~~
The discussion of theMODULE-TIME(see MODULE-TIME) function includes a sample program that uses this function.
Since this function has no arguments, no parenthesis should be specified.
MODULE-FORMATTED-DATE ~~~~~~~~~~~~~~~~~~~~~
The discussion of theMODULE-TIME(see MODULE-TIME) function includes a sample program that uses this function.
Since this function has no arguments, no parenthesis should be specified.
MODULE-ID ~~~~~~~~~
The discussion of theMODULE-TIME(see MODULE-TIME) function includes a sample program that uses this function.
Since this function has no arguments, no parenthesis should be specified.
MODULE-PATH ~~~~~~~~~~~
The discussion of theMODULE-TIME(see MODULE-TIME) function includes a sample program that uses this function.
Since this function has no arguments, no parenthesis should be specified.
MODULE-SOURCE ~~~~~~~~~~~~~
The discussion of theMODULE-TIME(see MODULE-TIME) function includes a sample program that uses this function.
Since this function has no arguments, no parenthesis should be specified.
MODULE-TIME ~~~~~~~~~~~
Since this function has no arguments, no parenthesis should be specified.
The following sample program uses all the MODULE- Functions:
IDENTIFICATION DIVISION.
PROGRAM-ID. DEMOMODULE.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
FUNCTION ALL INTRINSIC.
PROCEDURE DIVISION.
000-Main.
DISPLAY "MODULE-CALLER-ID = [" MODULE-CALLER-ID "]"
DISPLAY "MODULE-DATE = [" MODULE-DATE "]"
DISPLAY "MODULE-FORMATTED-DATE = [" MODULE-FORMATTED-DATE "]"
DISPLAY "MODULE-ID = [" MODULE-ID "]"
DISPLAY "MODULE-PATH = [" MODULE-PATH "]"
DISPLAY "MODULE-SOURCE = [" MODULE-SOURCE "]"
DISPLAY "MODULE-TIME = [" MODULE-TIME "]"
STOP RUN
.
The program produces this output when executed:
MODULE-CALLER-ID = [] MODULE-DATE = [20120614] MODULE-FORMATTED-DATE = [Jun 14 2012 15:07:45] MODULE-ID = [DEMOMODULE] MODULE-PATH = [E:\Programs\Demos\DEMOMODULE.exe] MODULE-SOURCE = [DEMOMODULE.cbl] MODULE-TIME = [150745]
MONETARY-DECIMAL-POINT ~~~~~~~~~~~~~~~~~~~~~~
On UNIX (including OSX, Windows/Cygwin and Windows/MinGW) systems, your locale is established via the
Using theDECIMAL-POINT IS COMMA(see SPECIAL-NAMES) clause in your program will not affect the value returned by this function.
Since this function has no arguments, no parenthesis should be specified.
MONETARY-THOUSANDS-SEPARATOR ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
On UNIX (including OSX, Windows/Cygwin and Windows/MinGW) systems, your locale is established via the
Using theDECIMAL-POINT IS COMMA(see SPECIAL-NAMES) clause in your program will not affect the value returned by this function.
Since this function has no arguments, no parenthesis should be specified.
NUMERIC-DECIMAL-POINT ~~~~~~~~~~~~~~~~~~~~~
On UNIX (including OSX, Windows/Cygwin and Windows/MinGW) systems, your locale is established via the
Using theDECIMAL-POINT IS COMMA(see SPECIAL-NAMES) clause in your program will not affect the value returned by this function.
Since this function has no arguments, no parenthesis should be specified.
NUMERIC-THOUSANDS-SEPARATOR ~~~~~~~~~~~~~~~~~~~~~~~~~~~
On UNIX (including OSX, Windows/Cygwin and Windows/MinGW) systems, your locale is established via the
Using theDECIMAL-POINT IS COMMA(see SPECIAL-NAMES) clause in your program will not affect the value returned by this function.
Since this function has no arguments, no parenthesis should be specified.
NUMVAL(string) ~~~~~~
The <string> must have any of the following formats, where ’#’ represents a sequence of one or more decimal digits:
There must be at least one digit character in the string.
Leading and/or trailing spaces are allowed, as are spaces before and/or after the sign, CR and DB characters.
NUMVAL-C(string[,symbol]) ~~~~~~~~
The optional <symbol> character represents the currency symbol (a single-character group item,USAGE DISPLAYelementary item or alphanumeric literal) that may be used as the currency character in <string>. If no <symbol> is specified, the value that would be returned by theCURRENCY-SYMBOLintrinsic function (see CURRENCY-SYMBOL) will be used.
<string> may have any of the following formats, where ’#’ represents a sequence of one or more decimal digits and ’$’ represents the <symbol> character:
There must be at least one digit character in the string.
Leading and/or trailing spaces are allowed, as are spaces before and/or after the currency symbol, sign, CR and DB characters.
NUMVAL-F(char) ~~~~~~~~
There must be at least one digit character both before and after theEin the string.
Leading and/or trailing spaces are allowed, as are spaces before and/or after any sign characters.
ORD(char) ~~~
For example, assuming the program is using the standard ASCII collating sequence,ORD('!')returns 34 because "!" is the 34th ASCII character. If you are using this function to convert an ASCII character to its numeric value, you must subtract one from the result.
The following code is an alternative approach when you just wish to convert an ASCII character to its numeric equivalent:
01 Char-Value.
05 Numeric-Value USAGE BINARY-CHAR.
…
MOVE "character" TO Char-Value
Numeric-Valuenow has the numeric value ofcharacter
ORD-MAX(char-1 [, char-2 ]...) ~~~~~~~
For example, assuming the program is using the standard ASCII collating sequence,ORD-MAX('Z', 'z', '!')returns 2 because the 2nd character in the argument list (the ASCII character ’z’) occurs after ’Z’ and ’!’ in the program collating sequence. Each <char-n> argument may be a group item,USAGE DISPLAYelementary item or alphanumeric literal.
ORD-MIN(char-1 [, char-2 ]...) ~~~~~~~
For example, assuming the program is using the standard ASCII collating sequence,ORD-MIN('Z', 'z', '!')returns 3 because the 3rd character in the argument list (the ASCII character ’!’) occurs before ’Z’ and ’z’ in the program collating sequence. Each <char-n> argument may be a group item,USAGE DISPLAYelementary item or alphanumeric literal.
PI ~~
Since this function has no arguments, no parenthesis should be specified.
PRESENT-VALUE(rate, value-1 [, value-2 ]) ~~~~~~~~~~~~~
All arguments are numeric data items and/or numeric literals.
RANDOM[(seed)] ~~~~~~
The purpose of the optional <seed> argument, is to initialize the chain of pseudo-random numbers that will be returned by the function. Not only will calls to this function using the same <seed> value return the same pseudo-random number, but so will all subsequent executions of the function without a <seed>. This is actually a good thing when you are testing your program because you can rely on always receiving the same sequence of "random" numbers if you always start using the same <seed>.
The <seed> may be any form of literal or data item. If <seed> is numeric, its numeric value will serve as the seed value. If <seed> is alphanumeric, a value for it will be determined as if it were used as an argument toNUMVAL(see NUMVAL).
Take, for example, the following sample program:
IDENTIFICATION DIVISION.
PROGRAM-ID. DEMORANDOM.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Pseudo-Random-Number USAGE COMP-1.
PROCEDURE DIVISION.
000-Main.
MOVE FUNCTION RANDOM(1) TO Pseudo-Random-Number
DISPLAY Pseudo-Random-Number
PERFORM 4 TIMES
MOVE FUNCTION RANDOM TO Pseudo-Random-Number
DISPLAY Pseudo-Random-Number
END-PERFORM
STOP RUN
.
Every time this program is executed, it will produce the same output, because the same sequence of pseudo-random numbers will be generated:
0.41
0.18467
0.63340002
0.26499999
0.19169
It is worth mentioning that if the first execution ofRANDOMin your program lacks a <seed> argument, the result will be exactly as if that execution were coded with a <seed> argument value of 1.
Once your program has been thoroughly tested, you’ll want different sequences to be generated each time the program runs. One possible way to accomplish this is to use a <seed> that is likely to be different every time the program is executed, as is likely to be the case if the firstMOVEstatement in the previous example were replaced by this:
MOVE RANDOM(FUNCTION CURRENT-DATE(1:16))
TO Pseudo-Random-Number
The first 16 characters returned by theCURRENT-DATE(see CURRENT-DATE) function will be a number in the format "YYYYMMDDhhmmssnn", where "YYYYMMDD" is the current calendar date and "hhmmssnn" is the current time of day to the one one-hundredth of a second. Since two different executions of the program will never get identicalCURRENT-DATEvalues (unless they are executed in extremely close time frames to one another), using those first sixteen characters as theRANDOMseed will guarantee that receiving a duplicate sequence of pseudo-random numbers in two different executions of the program will be HIGHLY unlikely.
RANGE(number-1 [, number-2 ]...) ~~~~~
All <number-n> arguments are numeric data items and/or numeric literals.
REM(number,divisor) ~~~
REVERSE(string) ~~~~~~~
SECONDS-FROM-FORMATTED-TIME(format,time) ~~~~~~~~~~~~~~~~~~~~~~~~~~~
The <time> string must contain hours, minutes and seconds. The time argument may be specified as a group item,USAGE DISPLAYelementary item or an alphanumeric literal.
The <format> argument is a string (a group item,USAGE DISPLAYelementary item or an alphanumeric literal) documenting the format of <time> using "hh", "mm" and "ss" to denote where the respective time information can be found. Any other characters found in <format> represent character positions that will be ignored. For example, a format ofhhmmssindicates that <time> will be treated as a six-digit string value where the first two characters are the number of hours, the next two represent minutes and the last two represent seconds. A <format> ofhh:mm:ss however, describes <time> as an eight-character string where characters 3 and 6 will be ignored.
SECONDS-PAST-MIDNIGHT ~~~~~~~~~~~~~~~~~~~~~
Since this function has no arguments, no parenthesis should be specified.
SIGN(number) ~~~~
SIN(angle) ~~~
The <angle> is assumed to be a value expressed in radians. If you need to determine the sine of an angle measured in degrees, you first need to convert that angle to radians as follows:
COMPUTE <radians> = ( <degrees> * FUNCTION PI) / 180SQRT(number) ~~~~
The following two statements produce identical results:
01 Result PIC 9(4).9(10).
…
MOVE FUNCTION SQRT(15) TO Result
COMPUTE Result = 15 ^ 0.5
STANDARD-DEVIATION(number-1 [, number-2 ]...) ~~~~~~~~~~~~~~~~~~
STORED-CHAR-LENGTH(string) ~~~~~~~~~~~~~~~~~~
SUBSTITUTE(string, from-1, to-1 [, from-n, to-n ]...) ~~~~~~~~~~
The <from-n> strings must match sequences in <string> exactly with regard to value and case.
A <from-n> string does not have to be the same length as its corresponding <to-n> string.
All arguments are group items, <USAGE DISPLAY> elementary items or alphanumeric literals.
A null <to-n> string will be treated as a single space.
SUBSTITUTE-CASE(string, from-1, to-1 [, from-n, to-n ]...) ~~~~~~~~~~~~~~~
All arguments are group items,USAGE DISPLAYelementary items or alphanumeric literals.
SUM(number-1 [, number-2 ]...) ~~~
TAN(angle) ~~~
The <angle> is assumed to be a value expressed in radians. If you need to determine the tangent of an angle measured in degrees, you first need to convert that angle to radians as follows:
COMPUTE <radians> = ( <degrees> * FUNCTION PI) / 180TEST-DATE-YYYYMMDD(date) ~~~~~~~~~~~~~~~~~~
A valid date is one of the form yyyymmdd in the range 1601/01/01 to 9999/12/31, with no more than the expected maximum number of days in the month, accounting for leap year.
If the <date> is valid, a 0 value is returned. If it isn’t, a value of 1, 2 or 3 is returned signalling the problem lies with the year, month or day, respectively.
TEST-DATE-YYYYDDD(date) ~~~~~~~~~~~~~~~~~
A valid date is one of the form yyyyddd in the range 1601001 to 9999365. Leap year is accounted for in determining the maximum number of days in a year.
If the date is valid, a 0 value is returned. If it isn’t, a value of 1 or 2 is returned signalling the problem lies with the year or day, respectively.
TEST-NUMVAL(string) ~~~~~~~~~~~
Note that these errors include but are not limited to: argument (string) is zero length, contains only spaces or contains valid characters but is incomplete, such as the string "+.".
TEST-NUMVAL-C(string[,symbol]) ~~~~~~~~~~~~~
Note that these errors include but are not limited to: argument (string) is zero length, contains only spaces or contains valid characters but is incomplete, such as the string "+.".
The optional <symbol> argument serves the same function — and has the same default and possible values — as the corresponding argument of theNUMVAL-Cfunction.
TEST-NUMVAL-F(string) ~~~~~~~~~~~~~
Note that these errors include but are not limited to: argument (string) is zero length, contains only spaces or contains valid characters but is incomplete, such as the string "+.".
TRIM(string [, LEADING|TRAILING ]) ~~~~ ~~~~~~~ ~~~~~~~~
The second argument is specified as a keyword, not a quoted string or identifier. If no second argument is specified, both leading and trailing spaces will be removed. The case (upper, lower or mixed) of this argument is irrelevant.
UPPER-CASE(string) ~~~~~~~~~~
What constitutes a "letter" (or upper/lower case too, for that manner) may be influenced through the use of aCHARACTER CLASSIFICATION(see OBJECT-COMPUTER).
VARIANCE(number-1 [, number-2 ]...) ~~~~~~~~
WHEN-COMPILED ~~~~~~~~~~~~~
Since this function has no arguments, no parenthesis should be specified.
Unlike theWHEN-COMPILEDspecial register, which has an ASCII value of the compilation date/time in the format "mm/dd/yyhh.mm.ss", theWHEN-COMPILEDintrinsic function returns the compilation date/time as an ASCII string in the format "yyyymmddhhmmssnnooooo", where "yyyymmdd" is the date, "hhmmss" is the time, "nn" is the hundredths of a second component of the compilation time, if available (or "00" if it isn’t) and "ooooo" is the time zone offset from GMT.
If the-fintrinsics=WHEN-COMPILEDswitch or-fintrinsics=ALLswitch is specified to the compiler or theREPOSITORY(see REPOSITORY) paragraph specifies eitherFUNCTION WHEN-COMPILED INTRINSICorFUNCTION ALL INTRINSIC then references toWHEN-COMPILED(without a leadingFUNCTIONkeyword will always reference this intrinsic function and there will be no way to access theWHEN-COMPILEDspecial register.
YEAR-TO-YYYY(yy [, yy-cutoff ]) ~~~~~~~~~~~~
The optional <yy-cutoff> argument is the year cutoff used to delineate centuries; if <yy> meets or exceeds this cutoff value, the result will be 19yy; if <yy> is less than the cutoff, the result will be 20yy. The default cutoff value if no second argument is given will be 50.
Both arguments must be numeric data items or numeric literals.
ACCEPT { identifier-1 } [ FROM mnemonic-name-1 ]
~~~~~~ ~~~~
{ OMITTED }
~~~~~~~
[ END-ACCEPT ]
~~~~~~~~~~ FROMclause is specified,FROM CONSOLEis assumed. CONSOLESTDINSYSINorSYSIPT or a user-defined (see SPECIAL-NAMES) mnemonic name attached to one of those four device names. CONSOLE or from the system-standard input (pipe 0 =STDINSYSINorSYSIPT and will be saved in <identifier-1>. NUMVALintrinsic function (see NUMVAL), except that none of the trailing sign formats are honoured. ACCEPT identifier-1
~~~~~~
FROM { COMMAND-LINE }
~~~~ { ~~~~~~~~~~~~ }
{ ARGUMENT-NUMBER }
{ ~~~~~~~~~~~~~~~ }
{ ARGUMENT-VALUE }
{ ~~~~~~~~~~~~~~ }
{ [ ON EXCEPTION imperative-statement-1 ] }
{ ~~~~~~~~~ }
{ [ NOT ON EXCEPTION imperative-statement-2 ] }
[ END-ACCEPT ] ~~~ ~~~~~~~~~
~~~~~~~~~~
ONis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. COMMAND-LINE ARGUMENT-NUMBER ARGUMENT-VALUE ON EXCEPTIONandNOT ON EXCEPTIONclauses may be used to detect and react to the failure or success, respectively, of an attempt to retrieve anARGUMENT-VALUE See ON EXCEPTION + NOT ON EXCEPTION, for additional information. ACCEPT identifier-1
~~~~~~
FROM { ENVIRONMENT-VALUE }
~~~~ { ~~~~~~~~~~~~~~~~~ }
{ ENVIRONMENT { literal-1 } }
{ ~~~~~~~~~~~ { identifier-1 } }
[ ON EXCEPTION imperative-statement-1 ]
~~~~~~~~~
[ NOT ON EXCEPTION imperative-statement-2 ]
~~~ ~~~~~~~~~
[ END-ACCEPT ]
~~~~~~~~~~
ONis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. ENVIRONMENT-VALUE ENVIRONMENT ON EXCEPTIONandNOT ON EXCEPTIONclauses may be used to detect and react to an attempt to retrieve the value of a non-existent environment variable or the successful retrieval of an environment variable’s value, respectively. See ON EXCEPTION + NOT ON EXCEPTION, for additional information. ACCEPT { identifier-1 }
~~~~~~
{ OMITTED }
~~~~~~~
[{ FROM EXCEPTION-STATUS }]
~~~~ ~~~~~~~~~~~~~~~~
[{ FROM CRT ] [ MODE IS BLOCK ]}
~~~~ ~~~ ~~~~ ~~~~~
[ AT { | LINE NUMBER { integer-1 } | } ]
~~ { | ~~~~ { identifier-2 } | }
{ | COLUMN|COL|POSITION NUMBER { integer-2 } | }
{ | ~~~~~~ ~~~ ~~~~~~~~ { identifier-3 } | }
{ }
{ { integer-3 } }
{ { identifier-4 } }
[ WITH [ Attribute-Specification ]...
~~~~
[ LOWER|UPPER ]
~~~~~ ~~~~~
[ SCROLL { UP } [ { integer-4 } LINE|LINES ] ]
~~~~~~ { ~~ } { identifier-5 }
{ DOWN }
~~~~
[ TIMEOUT|TIME-OUT AFTER { integer-5 } ]
~~~~~~~ ~~~~~~~~ { identifier-6 }
[ CONVERSION ]
~~~~~~~~~~
[ UPDATE ] ]
~~~~~~
[ ON EXCEPTION imperative-statement-1 ]
~~~~~~~~~
[ NOT ON EXCEPTION imperative-statement-2 ]
~~~ ~~~~~~~~~
[ END-ACCEPT ]
~~~~~~~~~~ TheFROM CRT
AFTERISNUMBERandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. COLUMNCOLandPOSITIONare interchangeable. TIMEOUTandTIME-OUTare interchangeable. SCREEN SECTION(see SCREEN SECTION), anyAT <Attribute-Specification>,LOWERUPPERorSCROLLclauses will be ignored. In these cases, an impliedDISPLAY(see DISPLAY screen-data-item) of <identifier-1> will occur before input is accepted. Coding an explicitDISPLAY identifier-1before anACCEPT identifier-1is redundant and will incur the performance penalty of painting the screen contents twice. ATclauses provide a means of positioning the cursor to a specific spot on the screen before the screen is read. One or the other (but not both) may be used, as follows: LINEandCOLUMNclauses provide one mechanism for specifying the line and column position to which the cursor will be positioned before allowing the user to enter data. In the absence of one or the other, a value of 1 will be assumed for the one that is missing. The author’s personal preference, however, is to explicitly code both. ACCEPT WITHoptions (including the various individual <Attribute-Specifications>) should be coded only once. ACCEPTstatement — these are the same as those allowed forSCREEN SECTIONdata items. A particular <Attribute-Specification> may be used only once in anyACCEPT AUTO(see AUTO),AUTO-SKIP(see AUTO-SKIP),AUTOTERMINATE(see AUTOTERMINATE),TAB
BACKGROUND-COLOR(see BACKGROUND-COLOR) BEEP(see BEEP),BELL(see BELL) BLINK(see BLINK) FOREGROUND-COLOR(see FOREGROUND-COLOR) FULL(see FULL),LENGTH-CHECK(see LENGTH-CHECK) HIGHLIGHT(see HIGHLIGHT) LEFTLINE(see LEFTLINE) LOWLIGHT(see LOWLIGHT) OVERLINE(see OVERLINE) PROMPT(see PROMPT) PROTECTED(see PROTECTED) REQUIRED(see REQUIRED),EMPTY-CHECK(see EMPTY-CHECK) REVERSE-VIDEO(see REVERSE-VIDEO) SECURE(see SECURE),NO-ECHO(see NO-ECHO) UNDERLINE(see UNDERLINE) SCROLL TIMEOUT ACCEPTstatement will be terminated by any of the following events: TIMEOUTtimer — this will be treated as if the Enter key had been pressed with no data being entered. SCREEN SECTION PICTURE(see PICTURE) clause of that item. This will be enforced at runtime by theACCEPTstatement. NUMVALintrinsic function (see NUMVAL) input (no decimal points are allowed, however). The value stored into the screen data item will be as if the input were passed to that function. NUMVAL-Cintrinsic function (see NUMVAL-C) input (again, no decimal points are allowed). The value stored into the screen data item will be as if the input were passed to that function. SCREEN SECTION PICTURE(see PICTURE) clause of that item, although that will not be enforced by theACCEPTstatement. You may useClass Conditions(see Class Conditions) after the data is accepted to enforce the data type. NUMVALintrinsic function (see NUMVAL) input (no decimal points are allowed, however). The value stored into <identifier-1> will be as if the input were passed to that function. NUMVAL-Cintrinsic function (see NUMVAL-C) input (again, no decimal points are allowed). The value stored into <identifier-1> will be as if the input were passed to that function. ON EXCEPTIONandNOT ON EXCEPTIONclauses may be used to detect and react to the failure or success, respectively, of the screen I/O attempt. See ON EXCEPTION + NOT ON EXCEPTION, for additional information. After this format of theACCEPTstatement is executed, the program’sCRT STATUS(see SPECIAL-NAMES) identifier will be populated with one of the following:
| Code | Meaning |
|---|---|
| 0000 | ENTER key pressed |
| 1001–1064 | F1–F64, respectively, were pressed |
| 2001 | PgUp was pressed |
| 2002 | PgDn,was pressed |
| 2003 | Up Arrow was pressed |
| 2004 | Down-Arrow was pressed |
| 2006 | PrtSc (Print Screen) was pressed |
| 2005 | Esc was pressed |
| 8000 | No data is available on screen ACCEPT |
| 9000 | Fatal screen I/O error |
EXCEPTION-STATUSclause may be used to detect exceptions from a prior arthmetic verb such as COMPUTE to recover any errors produced. These are recovered using the functionEXCEPTION-STATUS ACCEPT identifier-1 FROM { DATE [ YYYYMMDD ] }
~~~~~~ ~~~~ { ~~~~ ~~~~~~~~ }
{ DAY [ YYYYDDD ] }
{ ~~~ ~~~~~~~ }
{ DAY-OF-WEEK }
{ ~~~~~~~~~~~ }
[ END-ACCEPT ] { TIME }
~~~~~~~~~~ | Syntax | Data Retrieved | Format |
|---|---|---|
DATE |
Current date in Gregorian form | yymmdd |
DATE YYYYMMDD |
Current date in Gregorian form | yyyymmdd |
DAY |
Current date in Julian form | yyddd |
DAY YYYYDDD |
Current date in Julian form | yyyyddd |
TIME |
Time, including hundredths of a second (nn) | hhmmssnn |
ACCEPT identifier-1
~~~~~~
FROM { LINES|LINE-NUMBER }
~~~~ { ~~~~~ ~~~~~~~~~~~ }
{ COLS|COLUMNS }
{ ~~~~ ~~~~~~~ }
{ ESCAPE KEY }
~~~~~~ ~~~
[ END-ACCEPT ]
~~~~~~~~~~ LINESandLINE-NUMBERare interchangeable. COLSandCOLUMNSare interchangeable. LINES LINES COLUMNS or vertical LINES character counts — not pixels. CBL_GET_SCR_SIZEbuilt-in system subroutine (see CBL_GET_SCR_SIZE) for another way to retrieve this information. ESCAPE KEY ACCEPT identifier-1
~~~~~~
FROM { EXCEPTION STATUS }
~~~~ { ~~~~~~~~~ ~~~~~~ }
{ USER NAME }
~~~~ ~~~~
[ END-ACCEPT ]
~~~~~~~~~~ EXCEPTION STATUS PIC X(4)item. ACCEPT FROM Runtime-Infois to use theEXCEPTION-STATUSintrinsic function (see EXCEPTION-STATUS). USER NAME ACCEPT OMITTED ~~~~~~ 1. For console : See 6.17.1.1 (ACCEPT FROM CONSOLE Syntax) 2. For Screen : See 6.17.1.4 (ACCEPT screen-data-item Syntax) [ END-ACCEPT ] ~~~~~~~~~~
COB-SCR-INSERT COB-SCR-DELETE COB-SCR-BACKSPACE COB-SCR-KEY-HOME COB-SCR-KEY-END
ACCEPT exception-status-pic-9-4 FROM EXCEPTION-STATUS ~~~~~~ ~~~~ ~~~~~~~~~~~~~~~~ [ END-ACCEPT ] ~~~~~~~~~~
In WS:
01 exception-status pic 9(4).
..
In PD:
ACCEPT unexpected-rounding FROM EXCEPTION-STATUS
IF unexpected-rounding NOT EQUAL "0000" THEN
DISPLAY "Unexpected rounding. Code " unexpected-rounding
UPON SYSERR
END-IF
ADD { literal-1 }...
~~~ { identifier-1 }
TO { identifier-2
~~
[ ROUNDED [ MODE IS { AWAY-FROM-ZERO } ] ] }...
~~~~~~~ ~~~~ { ~~~~~~~~~~~~~~ }
{ NEAREST-AWAY-FROM-ZERO }
{ ~~~~~~~~~~~~~~~~~~~~~~ }
{ NEAREST-EVEN }
{ ~~~~~~~~~~~~ }
{ NEAREST-TOWARD-ZERO }
{ ~~~~~~~~~~~~~~~~~~~ }
{ PROHIBITED }
{ ~~~~~~~~~~ }
{ TOWARD-GREATER }
{ ~~~~~~~~~~~~~~ }
{ TOWARD-LESSER }
{ ~~~~~~~~~~~~~ }
{ TRUNCATION }
~~~~~~~~~~
[ ON SIZE ERROR imperative-statement-1 ]
~~~~ ~~~~~
[ NOT ON SIZE ERROR imperative-statement-2 ]
~~~ ~~~~ ~~~~~
[ END-ADD ]
~~~~~~~ ISandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. ROUNDED(see ROUNDED) clause available to each <identifier-2> will control how non-integer results will be saved. ON SIZE ERRORandNOT ON SIZE ERRORclauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-2> with an insufficient number of digit positions available to the left of any implied decimal point. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information. ADD { literal-1 }...
~~~ { identifier-1 }
[ TO identifier-2 ]
~~
GIVING { identifier-3
~~~~~~
[ ROUNDED [ MODE IS { AWAY-FROM-ZERO } ] ] }...
~~~~~~~ ~~~~ { ~~~~~~~~~~~~~~ }
{ NEAREST-AWAY-FROM-ZERO }
{ ~~~~~~~~~~~~~~~~~~~~~~ }
{ NEAREST-EVEN }
{ ~~~~~~~~~~~~ }
{ NEAREST-TOWARD-ZERO }
{ ~~~~~~~~~~~~~~~~~~~ }
{ PROHIBITED }
{ ~~~~~~~~~~ }
{ TOWARD-GREATER }
{ ~~~~~~~~~~~~~~ }
{ TOWARD-LESSER }
{ ~~~~~~~~~~~~~ }
{ TRUNCATION }
~~~~~~~~~~
[ ON SIZE ERROR imperative-statement-1 ]
~~~~ ~~~~~
[ NOT ON SIZE ERROR imperative-statement-2 ]
~~~ ~~~~ ~~~~~
[ END-ADD ]
~~~~~~~ ISandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. ROUNDED(see ROUNDED) clause available to each <identifier-3> will control how non-integer results will be saved. ON SIZE ERRORandNOT ON SIZE ERRORclauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-3> with an insufficient number of digit positions available to the left of any implied decimal point. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information. ADD CORRESPONDING identifier-1
~~~
TO identifier-2
~~
[ ROUNDED [ MODE IS { AWAY-FROM-ZERO } ] ]
~~~~~~~ ~~~~ { ~~~~~~~~~~~~~~ }
{ NEAREST-AWAY-FROM-ZERO }
{ ~~~~~~~~~~~~~~~~~~~~~~ }
{ NEAREST-EVEN }
{ ~~~~~~~~~~~~ }
{ NEAREST-TOWARD-ZERO }
{ ~~~~~~~~~~~~~~~~~~~ }
{ PROHIBITED }
{ ~~~~~~~~~~ }
{ TOWARD-GREATER }
{ ~~~~~~~~~~~~~~ }
{ TOWARD-LESSER }
{ ~~~~~~~~~~~~~ }
{ TRUNCATION }
~~~~~~~~~~
[ ON SIZE ERROR imperative-statement-1 ]
~~~~ ~~~~~
[ NOT ON SIZE ERROR imperative-statement-2 ]
~~~ ~~~~ ~~~~~
[ END-ADD ]
~~~~~~~ ISandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. ROUNDED(see ROUNDED) clause available to each <identifier-3> will control how non-integer results will be saved. ON SIZE ERRORandNOT ON SIZE ERRORclauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-3> with an insufficient number of digit positions available to the left of any implied decimal point. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information. ALLOCATE { expression-1 CHARACTERS } [ { INITIALIZED } ]
~~~~~~~~ { identifier-1 ~~~~~~~~~~ } { ~~~~~~~~~~~ }
{ INITIALISED }
[ RETURNING identifier-2 ] ~~~~~~~~~~~
~~~~~~~~~ INITIALIZEDandINITIALISEDare interchangeable. RETURNING <identifier-2>may not be specified in the same statement. BASED(see BASED) attribute. It may be an 01 item defined in the linkage section without theBASEDattribute, but using such a data item is not recommended. POINTER(see USAGE) data item. RETURNING INITIALIZED <expression-1> CHARACTERSoption is used,INITIALIZEDwill initialize the allocated memory block to binary zeros. IfINITIALIZEDis not used, the initial contents of allocated memory will be left to whatever rules of memory allocation are in effect for the operating system the program is running under. ALLOCATE My-01-Item
With this form, a block of storage equal in size to the defined size of My-01-Item (which must have been defined with theBASEDattribute) will be allocated. The address of that block of storage will become the base address of My-01-Item so that it and its subordinate data items become usable within the program.
A second (and equivalent) approach is:
ALLOCATE LENGTH OF My-01-Item CHARACTERS RETURNING The-Pointer SET ADDRESS OF My-01-Item TO The-Pointer
BASEDdata item either before its storage has been allocated or after its storage has been released (via theFREEstatement) will lead to "unpredictable results". That’s how reference manuals and standards specifications talk about this situation. In the author’s experience, the results are all too predictable — the program aborts from an attempt to reference an unallocated area of memory. ALTER procedure-name-1 TO PROCEED TO procedure-name-2 ~~~~~ ~~
PROCEEDandTO(the one afterPROCEED are optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. GO TO GO TOstatement in <procedure-name-1> is changed so that theGO TOstatement now transfers control to <procedure-name-2>, rather than to whatever procedure name was specified in the program source code. ALTERverb has been added to GnuCOBOL for the purpose of enabling GnuCOBOL to pass those National Institute of Standards and Technology (NIST) tests for the COBOL programming language that require support forALTER ALTERin new programs is STRONGLY discouraged. CALL [ { STDCALL } ] { literal-1 }
~~~~ { ~~~~~~~ } { identifier-1 }
{ STATIC }
{ ~~~~~~ }
{ mnemonic-name-1 }
[ USING CALL-Argument... ]
~~~~~
[ RETURNING|GIVING identifier-2 ]
~~~~~~~~~ ~~~~~~
[ ON OVERFLOW|EXCEPTION imperative-statement-1 ]
~~~~~~~~ ~~~~~~~~~
[ NOT ON OVERFLOW|EXCEPTION imperative-statement-2 ]
~~~ ~~~~~~~~ ~~~~~~~~~
[ END-CALL ]
~~~~~~~~ [ BY { REFERENCE } ]
{ ~~~~~~~~~ }
{ CONTENT }
{ ~~~~~~~ }
{ VALUE }
~~~~~
{ OMITTED }
{ ~~~~~~~ }
{ [ UNSIGNED ] [ SIZE IS { AUTO } ] [ { literal-2 } }
~~~~~~~~ ~~~~ { ~~~~ } { identifier-2 }
{ DEFAULT }
{ ~~~~~~~ }
{ integer-1 }
BYISandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. EXCEPTIONandOVERFLOWare interchangeable. GIVINGandRETURNINGare interchangeable. CALL Subprograms are not required to return to their callers, however, and are free to halt program execution if they wish. STATIC STATICoption will cause the linkage to the subroutine to be performed in such a way as to require the subroutine to be statically-linked with the calling program. Note that this enables static-linking to be used on a subroutine-by-subroutine selective basis. STDCALLoption allows system-standard calling conventions (as opposed to GnuCOBOL calling conventions) to be used when calling a subroutine. The definition of what constitutes "system standard" may vary from operating system to operating system. Use of this requires special knowledge about the linkage requirements of subroutines you are intending toCALL Subroutines written in GnuCOBOL do not need this option. CALL-CONVENTION(see SPECIAL-NAMES) clause. That clause associates a decimal integer value with <mnemonic-name-1> such that the individual bits set on or off in the binary equivalent of the integer affect linkage to the subroutine as described in the following chart. Those rows of the chart marked with a "No" in the "Supported" column represent bit positions (switch settings) in the integer value that are currently accepted (to provide compatibility to other COBOL implementations) if coded, but are otherwise unsupported. Note that bit 0 is the right-most bit in the binary value.
| Bit | Supported | Meaning if 0 | Meaning if 1 |
|---|---|---|---|
| 0 | No | Arguments will be passed in right-to-left sequence | Arguments will be passed in left-to-right sequence. |
| 1 | No | The calling program will flush processed arguments from the argument stack. | The called program (subroutine) will flush processed arguments from the argument stack. |
| 2 | Yes | TheRETURN-CODEspecial register (see Special Registers) will be updated in addition to anyRETURNINGorGIVINGdata item. |
TheRETURN-CODEspecial register will not be updated (but anyRETURNINGorGIVINGdata item still will). |
| 3 | Yes | If CALL "literal" is used, the subroutine will be located and linked in with the calling program at compile time or may be dynamically located and loaded at execution time, depending on compiler switch settings and operating system capabilities. | If CALL "literal" is used, the subroutine can only be located and linked with the calling program at compilation time. |
| 4 | No | OS/2 "OPTLINK" conventions will not be used to CALL the subprogram. | OS/2 "OPTLINK" conventions will be used to CALL the subprogram. |
| 5 | No | Windows 16-bit "thunking" will not be in effect. | Windows 16-bit "thunking" will be used to call the subroutine as a DLL. |
| 6 | Yes | The STDCALL convention will not be used. | The STDCALL convention, required to use the Microsoft Win32 API, will be used. |
Using theSTDCALLoption on aCALLstatement is equivalent to usingCALL-CONVENTION 8(only bit 3 set).
Using theSTATICoption on aCALLstatement is equivalent to usingCALL CONVENTION 64(only bit 6 set).
INITIAL(see IDENTIFICATION DIVISION) attribute specified on itsPROGRAM-IDclause, all of the subprogram’s data division data will be restored to its initial state each time the subprogram is executed, regardless of which entry-point within the subprogram is being referenced. This [re]-initialization behaviour will always apply to any subprogram’s local-storage (if any), regardless of the use (or not) ofINITIAL
USING BY REFERENCE BY CONTENT BY VALUE BYclause, the most-recently encounteredBYspecification on thatCALLstatement will be assumed. If the first argument specified on aCALLlacks aBYclause,BY REFERENCEwill be assumed. COB_MAX_FIELD_PARAMSin thecommon.hfile (found in thelibcobfolder) before you runmaketo build the compiler and run-time library. RETURNING ON OVERFLOWandNOT ON OVERFLOWclauses (orON EXCEPTIONandNOT ON EXCEPTION— they are interchangeable) may be used to detect and react to the failure or success, respectively, of an attempt toCALLthe subroutine. Failure, in this context, is defined as the inability to either locate or load the object code of the subroutine at execution time. See ON OVERFLOW + NOT ON OVERFLOW, for additional information. CANCEL { literal-1 }...
~~~~~~ { identifier-1 } CANCELstatement is subsequently re-executed, all data division storage for that module will once again be in it’s initial state. CANCELstatement actually physically unloads a dynamically-loaded module or simply marks it as logically-unloaded depends on the use and value of the CLOSE { file-name-1 [ { REEL|UNIT [ FOR REMOVAL ] } ] }...
~~~~~ { ~~~~ ~~~~ ~~~~~~~ }
{ WITH LOCK }
{ ~~~~ }
{ WITH NO REWIND }
~~ ~~~~~~ TheREEL
FORandWITHare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. REELandUNITare interchangeable. CLOSEstatement may only be executed against files that have been successfully opened. CLOSEwill write any remaining unwritten record buffers to the file (similar to anUNLOCKstatement (see UNLOCK)) and release any file locks for the file, regardless of open mode. A closed file will then be no longer available for subsequent I/O statements until it is once again OPENED. ORGANIZATION LINE SEQUENTIAL(see ORGANIZATION LINE SEQUENTIAL) orLINE ADVANCING(see LINE ADVANCING) file is closed, a final delimiter sequence will be written to the file to signal the termination point of the final data record in the file. This will only be necessary if the final record written to the file was written with theAFTER ADVANCING(see WRITE) option. COMMIT ~~~~~~
See theUNLOCKstatement (see UNLOCK) for additional details.
COMPUTE { identifier-1
~~~~~~~
[ ROUNDED [ MODE IS { AWAY-FROM-ZERO } ] }...
~~~~~~~ ~~~~ { ~~~~~~~~~~~~~~ }
{ NEAREST-AWAY-FROM-ZERO }
{ ~~~~~~~~~~~~~~~~~~~~~~ }
{ NEAREST-EVEN }
{ ~~~~~~~~~~~~ }
{ NEAREST-TOWARD-ZERO }
{ ~~~~~~~~~~~~~~~~~~~ }
{ PROHIBITED }
{ ~~~~~~~~~~ }
{ TOWARD-GREATER }
{ ~~~~~~~~~~~~~~ }
{ TOWARD-LESSER }
{ ~~~~~~~~~~~~~ }
{ TRUNCATION }
~~~~~~~~~~
=|EQUAL arithmetic-expression-1
~~~~~
[ ON SIZE ERROR imperative-statement-1 ]
~~~~ ~~~~~
[ NOT ON SIZE ERROR imperative-statement-2 ]
~~~ ~~~~ ~~~~~
[ END-COMPUTE ]
~~~~~~~~~~~ ISandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. EQUALis interchangeable with the use of= ROUNDED(see ROUNDED) clause available to each <identifier-1> will control how non-integer results will be saved. ON SIZE ERRORandNOT ON SIZE ERRORclauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined either as having an <identifier-3> with an insufficient number of digit positions available to the left of any implied decimal point or attempting to divide by zero. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information. CONTINUE ~~~~~~~~
CONTINUEstatement has no effect on the execution of the program. ELSE(see IF) orWHEN(see EVALUATE) clauses where no code is currently expected to be needed, but a place for code to handle the conditions in question is to be reserved in case it’s ever needed. DELETE file-name-1 RECORD
~~~~~~
[ INVALID KEY imperative-statement-1 ]
~~~~~~~
[ NOT INVALID KEY imperative-statement-2 ]
~~~ ~~~~~~~
[ END-DELETE ]
~~~~~~~~~~
KEYandRECORDare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. ORGANIZATIONof <file-name-1> cannot beORGANIZATION LINE SEQUENTIAL(see ORGANIZATION LINE SEQUENTIAL). SD(see File/Sort-Description)). SEQUENTIALaccess mode, the last input-output statement executed against <file-name-1> prior to the execution of theDELETEstatement must have been a successfully executed sequential-formatREADstatement (see Sequential READ). ThatREADwill therefore identify the record to be deleted. RELATIVEfile whoseACCESS MODE(see ORGANIZATION RELATIVE) is eitherRANDOMorDYNAMIC the record to be deleted is the one whose relative record number is currently the value of the field specified as the filesRELATIVE KEY INDEXEDfile whoseACCESS MODE(see ORGANIZATION INDEXED) isRANDOMorDYNAMIC the record to be deleted is the one whose primary key is currently the value of the field specified as theRECORD KEY INVALID KEYandNOT INVALID KEYclauses may be used to detect and react to the failure or success, respectively, of an attempt to delete a record. See INVALID KEY + NOT INVALID KEY, for additional information. INVALID KEYorNOT INVALID KEYclause may be specified for a file who’sACCESS MODE IS SEQUENTIAL DISPLAY { literal-1 }...
~~~~~~~ { identifier-1 }
[ UPON mnemonic-name-1 ]
~~~~
[ WITH NO ADVANCING ]
~~ ~~~~~~~~~
[ ON EXCEPTION imperative-statement-1 ]
~~~~~~~~~
[ NOT ON EXCEPTION imperative-statement-2 ]
~~~ ~~~~~~~~~
[ END-DISPLAY ]
~~~~~~~~~~~ ONandWITHare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. UPON When displaying upon theSTDERRorSYSERRdevices or to a <mnemonic-name-1> attached to one of those two devices, the output will be written to output pipe #2, which will normally cause the output to appear in the console output window. You may, if desired, redirect that output to a file by appending2> filenameto the end of the command that executes the program. This applies to both Windows (any type) or Unix versions of GnuCOBOL.
When displaying upon theCONSOLEPRINTERSTDOUTSYSLISTSYSLSTorSYSOUTdevices or to a <mnemonic-name-1> attached to one of them, the output will be written to output pipe #1, which will normally cause the output to appear in the console output window. You may, if desired, redirect that output to a file by appending1> filenameor simply> filenameto the end of the command that executes the program. This applies to both Windows (any type) or Unix versions of GnuCOBOL.
NO ADVANCING ON EXCEPTIONandNOT ON EXCEPTIONclauses may be used to detect and react to the failure or success, respectively, of an attempt to display output to the specified device. See ON EXCEPTION + NOT ON EXCEPTION, for additional information. DISPLAY { literal-1 }...
~~~~~~~ { identifier-1 }
UPON { ARGUMENT-NUMBER|COMMAND-LINE }
~~~~ { ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~ }
[ ON EXCEPTION imperative-statement-1 ]
~~~~~~~~~
[ NOT ON EXCEPTION imperative-statement-2 ]
~~~ ~~~~~~~~~
[ END-DISPLAY ]
~~~~~~~~~~~ ONis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. ARGUMENT-NUMBER DISPLAY UPON COMMAND-LINEwill influence subsequentACCEPT FROM COMMAND-LINEstatements (which will then return the value you displayed), but will not influence subsequentACCEPT FROM ARGUMENT-VALUEstatements — these will continue to return the original program execution parameters. ON EXCEPTIONandNOT ON EXCEPTIONclauses may be used to detect and react to the failure or success, respectively, of an attempt to display output to the specified item. See ON EXCEPTION + NOT ON EXCEPTION, for additional information. DISPLAY { literal-1 }... UPON { ENVIRONMENT-VALUE }
~~~~~~~ { identifier-1 } ~~~~ { ~~~~~~~~~~~~~~~~~ }
{ ENVIRONMENT-NAME }
~~~~~~~~~~~~~~~~
[ ON EXCEPTION imperative-statement-1 ]
~~~~~~~~~
[ NOT ON EXCEPTION imperative-statement-2 ]
~~~ ~~~~~~~~~
[ END-DISPLAY ]
~~~~~~~~~~~ ONis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. DISPLAYstatements. The following example sets the environment variable "MY_ENV_VAR" to a value of "Demonstration Value": DISPLAY "MY_ENV_VAR" UPON ENVIRONMENT-NAME DISPLAY "Demonstration Value" UPON ENVIRONMENT-VALUE
CALL 'SYSTEM'(see SYSTEM)) but will not be known to the shell or console window that started the GnuCOBOL program. SET ENVIRONMENT(see SET ENVIRONMENT) in lieu ofDISPLAYto set environment variables as it is much simpler. ON EXCEPTIONandNOT ON EXCEPTIONclauses may be used to detect and react to the failure or success, respectively, of an attempt to display output to the specified item. See ON EXCEPTION + NOT ON EXCEPTION, for additional information. DISPLAY identifier-1 [ UPON CRT|CRT-UNDER ]
~~~~~~~ ~~~~ ~~~ ~~~~~~~~~
[ AT { | LINE NUMBER { integer-1 } | } ]
~~ { | ~~~~ { identifier-2 } | }
{ | | }
{ | COLUMN|POSITION NUMBER { integer-2 } | }
{ | ~~~~~~ ~~~~~~~~ { identifier-3 } | }
{ }
{ { integer-3 } }
{ { identifier-4 } }
[ WITH [ DISPLAY-Attribute ]...
~~~~
[ SCROLL { UP } [ { integer-4 } LINE|LINES ] ]
~~~~~~ { ~~ } { identifier-5 }
{ DOWN }
~~~~
[ TIMEOUT|TIME-OUT AFTER { integer-5 } ]
~~~~~~~ ~~~~~~~~ { identifier-6 }
[ CONVERSION ] ]
~~~~~~~~~~
[ ON EXCEPTION imperative-statement-1 ]
~~~~~~~~~
[ NOT ON EXCEPTION imperative-statement-2 ]
~~~ ~~~~~~~~~
[ END-DISPLAY ]
~~~~~~~~~~~ TheUPON CRT
AFTERLINELINESNUMBERandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. COLUMNandPOSITIONare interchangeable. LINEandLINESare interchangeable. TIMEOUTandTIME-OUTare interchangeable. SCREEN SECTION(see SCREEN SECTION), anyAT <Attribute-Specification> andWITHclauses will be ignored. All field definition, cursor positioning and screen control will occur as a result of the screen section definition of <identifier-1>. ATclause is to define where on the screen <identifier-1> should be displayed. See ACCEPT screen-data-item, for additional information. WITHclause is to define the visual attributes that should be applied to <identifier-1> when it is displayed on the screen as well as other presentation-control characteristics. DISPLAYstatement — these are the same as those allowed forSCREEN SECTIONdata items. A particular <Attribute-Specification> may be used only once in anyDISPLAY BACKGROUND-COLOR(see BACKGROUND-COLOR) BEEP(see BEEP),BELL(see BELL) BLANK(see BLANK) BLINK(see BLINK) ERASE(see ERASE) FOREGROUND-COLOR(see FOREGROUND-COLOR) HIGHLIGHT(see HIGHLIGHT) LOWLIGHT(see LOWLIGHT) OVERLINE(see OVERLINE) REVERSE-VIDEO(see REVERSE-VIDEO) UNDERLINE(see UNDERLINE) WITHclause options. ON EXCEPTIONandNOT ON EXCEPTIONclauses may be used to detect and react to the failure or success, respectively, of the screen I/O attempt. See ON EXCEPTION + NOT ON EXCEPTION, for additional information. DIVIDE { literal-1 } INTO { identifier-2
~~~~~~ { identifier-1 } ~~~~
[ ROUNDED [ MODE IS { AWAY-FROM-ZERO } ] ] }...
~~~~~~~ ~~~~ { ~~~~~~~~~~~~~~ }
{ NEAREST-AWAY-FROM-ZERO }
{ ~~~~~~~~~~~~~~~~~~~~~~ }
{ NEAREST-EVEN }
{ ~~~~~~~~~~~~ }
{ NEAREST-TOWARD-ZERO }
{ ~~~~~~~~~~~~~~~~~~~ }
{ PROHIBITED }
{ ~~~~~~~~~~ }
{ TOWARD-GREATER }
{ ~~~~~~~~~~~~~~ }
{ TOWARD-LESSER }
{ ~~~~~~~~~~~~~ }
{ TRUNCATION }
~~~~~~~~~~
[ ON SIZE ERROR imperative-statement-1 ]
~~~~ ~~~~~
[ NOT ON SIZE ERROR imperative-statement-2 ]
~~~ ~~~~ ~~~~~
[ END-DIVIDE ]
~~~~~~~~~~ ISandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. ROUNDED(see ROUNDED) clause available to each <identifier-2> will control how non-integer results will be saved. ON SIZE ERRORandNOT ON SIZE ERRORclauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being numeric truncation caused by an <identifier-2> with an insufficient number of digit positions available to the left of any implied decimal point, or an attempt to divide by zero. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information. DIVIDE { literal-1 } INTO { literal-2 } GIVING { identifier-3
~~~~~~ { identifier-1 } ~~~~ { identifier-2 } ~~~~~~
[ ROUNDED [ MODE IS { AWAY-FROM-ZERO } ] ] }...
~~~~~~~ ~~~~ { ~~~~~~~~~~~~~~ }
{ NEAREST-AWAY-FROM-ZERO }
{ ~~~~~~~~~~~~~~~~~~~~~~ }
{ NEAREST-EVEN }
{ ~~~~~~~~~~~~ }
{ NEAREST-TOWARD-ZERO }
{ ~~~~~~~~~~~~~~~~~~~ }
{ PROHIBITED }
{ ~~~~~~~~~~ }
{ TOWARD-GREATER }
{ ~~~~~~~~~~~~~~ }
{ TOWARD-LESSER }
{ ~~~~~~~~~~~~~ }
{ TRUNCATION }
[ REMAINDER identifier-4 ] ~~~~~~~~~~
~~~~~~~~~
[ ON SIZE ERROR imperative-statement-1 ]
~~~~ ~~~~~
[ NOT ON SIZE ERROR imperative-statement-2 ]
~~~ ~~~~ ~~~~~
[ END-DIVIDE ]
~~~~~~~~~~ ISandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. REMAINDER ROUNDED(see ROUNDED) clause (if any) for that <identifier-3> to the move. REMAINDERclause is specified, the value of the one and only <identifier-3> (as stated earlier, ifREMAINDERis specified there may only be a single <identifier-3> coded on the statement) after it was assigned a value according to the previous rule will be multiplied by the value of <literal-1> or <identifier-1>; that result is then subtracted from the value of <literal-2> or <identifier-2> and that result is the value which is moved to <identifier-4>. ON SIZE ERRORandNOT ON SIZE ERRORclauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-2> with an insufficient number of digit positions available to the left of any implied decimal point, or an attempt to divide by zero. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information. DIVIDE { literal-1 } BY { literal-2 } GIVING { identifier-3
~~~~~~ { identifier-1 } ~~ { identifier-2 } ~~~~~~
[ ROUNDED [ MODE IS { AWAY-FROM-ZERO } ] ] }...
~~~~~~~ ~~~~ { ~~~~~~~~~~~~~~ }
{ NEAREST-AWAY-FROM-ZERO }
{ ~~~~~~~~~~~~~~~~~~~~~~ }
{ NEAREST-EVEN }
{ ~~~~~~~~~~~~ }
{ NEAREST-TOWARD-ZERO }
{ ~~~~~~~~~~~~~~~~~~~ }
{ PROHIBITED }
{ ~~~~~~~~~~ }
{ TOWARD-GREATER }
{ ~~~~~~~~~~~~~~ }
{ TOWARD-LESSER }
{ ~~~~~~~~~~~~~ }
{ TRUNCATION }
[ REMAINDER identifier-4 ] ~~~~~~~~~~
~~~~~~~~~
[ ON SIZE ERROR imperative-statement-1 ]
~~~~ ~~~~~
[ NOT ON SIZE ERROR imperative-statement-2 ]
~~~ ~~~~ ~~~~~
[ END-DIVIDE ]
~~~~~~~~~~ ISandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. REMAINDER ROUNDED(see ROUNDED) clause (if any) for that <identifier-3> to the move. REMAINDERclause is specified, the value of the one and only <identifier-3> (as stated earlier, ifREMAINDERis specified there may only be a single <identifier-3> coded on the statement) after it was assigned a value according to the previous rule will be multiplied by the value of <literal-2> or <identifier-2>; that result is then subtracted from the value of <literal-1> or <identifier-1> and that result is the value which is moved to <identifier-4>. ON SIZE ERRORandNOT ON SIZE ERRORclauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-2> with an insufficient number of digit positions available to the left of any implied decimal point, or an attempt to divide by zero. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information. ENTRY literal-1 [ USING ENTRY-Argument... ] ~~~~~ ~~~~~
[ BY { REFERENCE } ] identifier-1
{ ~~~~~~~~~ }
{ CONTENT }
{ ~~~~~~~ }
{ VALUE }
~~~~~ BYis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. ENTRYstatement in a nested subprogram, nor may you use it in any form of user-defined function. USING ENTRYstatement must be defined in the linkage section of the subroutine in which theENTRYstatement exists. CALLstatements (with regard to the use of upper- and lower-case letters) as it is specified on theENTRYstatement. REFERENCE EVALUATE Selection-Subject-1 [ ALSO Selection-Subject-2 ]...
~~~~~~~~ ~~~~
{ { WHEN Selection-Object-1 [ ALSO Selection-Object-2 ] }...
~~~~ ~~~~
[ imperative-statement-1 ] }...
[ WHEN OTHER
~~~~ ~~~~~
imperative-statement-other ]
[ END-EVALUATE ]
~~~~~~~~~~~~ { TRUE }
{ ~~~~ }
{ FALSE }
{ ~~~~~ }
{ expression-1 }
{ identifier-1 }
{ literal-1 } { ANY }
{ ~~~ }
{ TRUE }
{ ~~~~ }
{ FALSE }
{ ~~~~~ }
{ partial-expression-1 }
{ }
{ { expression-2 } [ THRU|THROUGH { expression-3 } ] }
{ { identifier-2 } ~~~~ ~~~~~~~ { identifier-3 } }
{ { literal-2 } { literal-3 } } THRUandTHROUGHare interchangeable. WHEN EVALUATEstatement. Any number of additional <Selection-Subject> clauses may be specified, using theALSO WHENclause (other than theWHEN OTHER THRU EVALUATEstatement will have its value matched against that of the corresponding <Selection-Object> on aWHENclause, in turn, until: WHENclause has each of its <Selection-Object>(s) successfully matched by the corresponding <Selection-Subject>; this will be referred to as the ’Selected WHEN clause’. WHENclauses (except for theWHEN OTHERclause, if any) has been exhausted. In this case, there is no ’Selected WHEN Clause’. WHENclause will be executed. END-EVALUATEor, if there is noEND-EVALUATE the first statement that follows the next period. If, however, the <imperative-statement-1> included aGO TOstatement, and thatGO TOwas executed, then control will transfer to the procedure named on theGO TOinstead. WHEN OTHERclause’s <imperative-statement-other> will be executed, if such a clause was coded. END-EVALUATEor the first statement that follows the next period if there is noEND-EVALUATE If,however, the <imperative-statement-other> included aGO TOstatement, and thatGO TOwas executed, then control will transfer to the procedure named on theGO TOinstead. WHENclause, at least one of the following must be true: ANY <Selection-Subject> = <Selection Object>is TRUE — See Relation Conditions, for the rules on how the comparison will be made. THRUclause of the <Selection-Object> <Selection-Subject> <Selection-Object>evaluates to TRUE IDENTIFICATION DIVISION.
PROGRAM-ID. DEMOEVALUATE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Test-Digit PIC 9(1).
88 Digit-Is-Odd VALUE 1, 3, 5, 7, 9.
88 Digit-Is-Prime VALUE 1, 3, 5, 7.
PROCEDURE DIVISION.
P1. PERFORM UNTIL EXIT
DISPLAY "Enter a digit (0 Quits): "
WITH NO ADVANCING
ACCEPT Test-Digit
IF Test-Digit = 0
EXIT PERFORM
END-IF
EVALUATE Digit-Is-Odd ALSO Digit-Is-Prime
WHEN TRUE ALSO FALSE
DISPLAY Test-Digit " is ODD"
WITH NO ADVANCING
WHEN TRUE ALSO TRUE
DISPLAY Test-Digit " is PRIME"
WITH NO ADVANCING
WHEN FALSE ALSO ANY
DISPLAY Test-Digit " is EVEN"
WITH NO ADVANCING
END-EVALUATE
EVALUATE Test-Digit
WHEN < 5
DISPLAY " and it's small too"
WHEN < 8
DISPLAY " and it's medium too"
WHEN OTHER
DISPLAY " and it's large too"
END-EVALUATE
END-PERFORM
DISPLAY "Bye!"
STOP RUN
.
Console output when run (user input follows the colons on the prompts for input):
Enter a digit (0 Quits): 1 1 is PRIME and it's small too Enter a digit (0 Quits): 2 2 is EVEN and it's small too Enter a digit (0 Quits): 3 3 is PRIME and it's small too Enter a digit (0 Quits): 4 4 is EVEN and it's small too Enter a digit (0 Quits): 5 5 is PRIME and it's medium too Enter a digit (0 Quits): 6 6 is EVEN and it's medium too Enter a digit (0 Quits): 7 7 is PRIME and it's medium too Enter a digit (0 Quits): 8 8 is EVEN and it's large too Enter a digit (0 Quits): 9 9 is ODD and it's large too Enter a digit (0 Quits): 0 Bye!
EXIT [ { PROGRAM } ]
~~~~ { ~~~~~~~ }
{ FUNCTION }
{ ~~~~~~~~ }
{ PERFORM [ CYCLE ] }
{ ~~~~~~~ ~~~~~ }
{ SECTION }
{ ~~~~~~~ }
{ PARAGRAPH }
~~~~~~~~~ EXIT PROGRAMstatement is not legal anywhere within a user-defined function. EXIT FUNCTIONstatement cannot be used anywhere within a subroutine. EXIT PROGRAMnorEXIT FUNCTIONmay be used within aUSE GLOBALroutine inDECLARATIVES(see DECLARATIVES). EXITstatement with none of the optional clauses: EXITstatement is used, it must be the only statement in the procedure (paragraph or section) in which it occurs. EXITstatement simply provides a common "GO TO" end point for a series of procedures, as may be seen in the following example: 01 Switches.
05 Input-File-Switch PIC X(1).
88 EOF-On-Input-File VALUE Y FALSE N.
…
SET EOF-On-Input-File TO FALSE.
PERFORM 100-Process-A-Transaction THRU 199-Exit
UNTIL EOF-On-Input-File.
…
100-Process-A-Transaction.
READ Input-File AT END
SET EOF-On-Input-File TO TRUE
GO TO 199-Exit
END-READ.
IF Input-Rec of Input-File = SPACES
GO TO 199-Exit *> IGNORE BLANK RECORDS!
END-IF.
<<<process the record just read>>>
199-Exit.
EXIT.
EXITstatement takes no other run-time action. EXIT PARAGRAPHandEXIT SECTIONstatements: EXIT PARAGRAPHstatement orEXIT SECTIONstatement resides in a paragraph within the scope of a proceduralPERFORM(see Procedural PERFORM), control will be returned back to thePERFORMfor evaluation of anyTIMESVARYINGand/orUNTILclauses. EXIT PARAGRAPHstatement orEXIT SECTIONstatement resides outside the scope of a proceduralPERFORM control simply transfers to the first executable statement in the next paragraph EXIT PARAGRAPH or section EXIT SECTION. GO TOby utilizing anEXIT PARAGRAPHstatement. 01 Switches.
05 Input-File-Switch PIC X(1).
88 EOF-On-Input-File VALUE Y FALSE N.
…
SET EOF-On-Input-File TO FALSE.
PERFORM 100-Process-A-Transaction
UNTIL EOF-On-Input-File.
…
100-Process-A-Transaction.
READ Input-File AT END
SET EOF-On-Input-File TO TRUE
EXIT PARAGRAPH
END-READ.
IF Input-Rec of Input-File = SPACES
EXIT PARAGRAPH *> IGNORE BLANK RECORDS!
END-IF.
<<<process the record just read>>>
EXIT PERFORMandEXIT PERFORM CYCLEstatements: EXIT PERFORMandEXIT PERFORM CYCLEstatements are intended to be used in conjunction with an in-linePERFORMstatement (see Inline PERFORM). EXIT PERFORM CYCLEstatement will terminate the current iteration of the in-linePERFORM giving control to anyTIMESVARYINGand/orUNTILclauses for them to determine if another cycle needs to be performed. EXIT PERFORMstatement will terminate the in-line PERFORM outright, transferring control to the first statement following theEND-PERFORM(if there is one) or to the next sentence following thePERFORMif there is noEND-PERFORM PERFORMalong withEXIT PERFORMandEXIT PERFORM CYCLEstatements: PERFORM FOREVER
READ Input-File AT END
EXIT PERFORM
END-READ
IF Input-Rec of Input-File = SPACES
EXIT PERFORM CYCLE *> IGNORE BLANK RECORDS!
END-IF
<<<process the record just read>>>
END PERFORM
EXIT PROGRAMandEXIT FUNCTIONstatements: EXIT PROGRAMandEXIT FUNCTIONstatements terminate the execution of a subroutine (i.e. a program that has been CALLed by another) or user-defined function, respectively, returning control back to the calling program. EXIT PROGRAMstatement returns control back to the statement following theCALL(see CALL) of the subprogram. AnEXIT FUNCTIONstatement returns control back to the processing of the statement in the calling program that invoked the user-defined function. EXIT PROGRAMnorEXIT FUNCTIONstatements will take any action. GOBACKstatement (see GOBACK) — a standard language element; theGOBACKstatement should be strongly considered as the preferred alternative to bothEXIT PROGRAMandEXIT FUNCTIONfor new subprograms. FREE { [ ADDRESS OF ] identifier-1 }...
~~~~ ~~~~~~~ ADDRESS OFclause is optional and may be included, or not, at the discretion of the programmer. The presence or absence of this clause has no effect upon the program. USAGE(see USAGE) ofPOINTER or it must be an 01-level data item with theBASED(see BASED) attribute. USAGE POINTERdata item and it contains a valid address, theFREEstatement will release the memory block the pointer references. In addition, anyBASEDdata items that the pointer was used to provide an address for will become un-based and therefore un-usable. If <identifier-1> did not contain a valid address, no action will be taken. BASEDdata item and that data item is currently based (meaning it currently has memory allocated to it), its memory is released and <identifier-1> will become un-based and therefore un-usable. If <identifier-1> was not based, no action will be taken. GENERATE { report-name-1 }
~~~~~~~~ { identifier-1 } DETAIL(see RWCS Lexicon) report group. FDaREPORTclause exists for the report in which <identifier-1> is a detail group must be opened forOUTPUTorEXTENDat the time theGENERATEis executed. See OPEN, for information on file open modes. DETAILgroup must have been successfully initiated via theINITIATEstatement (see INITIATE) and not yet terminated via theTERMINATEstatement (see TERMINATE) at the time theGENERATEis executed. GENERATEstatement of this form is executed against a report, the report is said to be a ’detail report’ RDdefined for it in the report section. CONTROL(see RWCS Lexicon) group defined for <report-name-1>. DETAILgroup defined for <report-name-1>. FDaREPORT <report-name-1>clause exists must be open forOUTPUTorEXTENDat the time the GENERATE is executed. GENERATEis executed. See OPEN, for information on file open modes. DETAILgroup which is defined for <report-name-1> will be processed but will not actually be presented to any report page. This will allow summary processing to take place. If allGENERATEstatements are of this form, the report is said to be a ’summary report’ GENERATEstatement for a report is executed, the contents of all control fields are saved so they may be referenced during the processing of subsequentGENERATEstatements. GENERATE it is determined that a control field has changed value (ie. a control break has occurred), the appropriate control footing and control heading processing will take place and a snapshot of the current values of all control fields will again be saved. GOBACK ~~~~~~
GOBACKbehaves like anEXIT PROGRAMorEXIT FUNCTIONstatement, respectively. GOBACKwill act as aSTOP RUNstatement. GO TO procedure-name-1 ~~
TOis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. GO TOstatement appears in a consecutive sequence of imperative statements (see Imperative Statement) within a sentence, it must be the final statement in the sentence. GO TOis executed within the scope of… PERFORM(see PERFORM), thePERFORMis terminated as control of execution transfers to <procedure-name-1>. PERFORM(see PERFORM), and <procedure-name-1> lies outside the scope of thatPERFORM thePERFORMis terminated as control of execution transfers to <procedure-name-1>. MERGEstatement (see MERGE)OUTPUT PROCEDUREor within the scope of either anINPUT PROCEDUREorOUTPUT PROCEDUREof aSORTstatement (see File-Based SORT), and <procedure-name-1> lies outside the scope of that procedure, theSORTorMERGEoperation is terminated as control of execution transfers to <procedure-name-1>. Any sorted or merged data accumulated to that point is lost. GO TO procedure-name-1...
~~
DEPENDING ON identifier-1
~~~~~~~~~ TOis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. PICTURE(see PICTURE) and/orUSAGE(see USAGE) of the specified <identifier-1> must be such as to define it as a numeric, unedited, preferably unsigned integer data item. If control of execution is transferred to a procedure named on the statement, and theGO TOis executed within the scope of…
PERFORM(see PERFORM), thePERFORMis terminated as control of execution transfers to the procedure named on the statement. PERFORM(see PERFORM), and <procedure-name-1> lies outside the scope of thatPERFORM thePERFORMis terminated as control of execution transfers to the procedure named on the statement. MERGEstatement (see MERGE)OUTPUT PROCEDUREor within the scope of either anINPUT PROCEDUREorOUTPUT PROCEDUREof aSORTstatement (see File-Based SORT), and <procedure-name-1> lies outside the scope of that procedure, theSORTorMERGEoperation is terminated as control of execution transfers to the procedure named on the statement. Any sorted or merged data accumulated to that point is lost. GO TO GO TO ... DEPENDING ONmay be used in a real application situation, and compares it against an alternative —EVALUATE(see EVALUATE). GO TO DEPENDING ON Example Equivalent EVALUATE Example
================================= =================================
GO TO EVALUATE Acct-Type
ACCT-TYPE-1 WHEN 1
ACCT-TYPE-2 <<< Handle Acct Type 1 >>>
ACCT-TYPE-3 WHEN 2
DEPENDING ON Acct-Type. <<< Handle Acct Type 2 >>>
<<< Invalid Acct Type >>> WHEN 3
GO TO All-Done. <<< Handle Acct Type 3 >>>
Acct-Type-1. WHEN OTHER
<<< Handle Acct Type 1 >>> <<< Invalid Acct Type >>>
GO TO All-Done. END-EVALUATE.
Acct-Type-2.
<<< Handle Acct Type 2 >>>
GO TO All-Done.
Acct-Type-3.
<<< Handle Acct Type 3 >>>
All-Done.
EVALUATEstatement to that of this form of theGO TOstatement. IF conditional-expression
~~
THEN { imperative-statement-1 }
{ NEXT SENTENCE }
~~~~ ~~~~~~~~
[ ELSE { imperative-statement-2 } ]
~~~~ { NEXT SENTENCE }
~~~~ ~~~~~~~~
[ END-IF ]
~~~~~~ THENis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. NEXT SENTENCEand theEND-IFscope terminator in the sameIFstatement. ELSE ELSEclause is present and conditional-expression evaluates to false, then (and only then) <imperative-statement-2> will be executed. Once <imperative-statement-2> has been executed, control falls into the first statement following theEND-IFor to the first statement of the next sentence if there is noEND-IFclause. NEXT SENTENCE NEXT SENTENCEwas needed for COBOL programs that were coded according to pre-1985 standards that wish to nest oneIFstatement inside another. See Use of VERB/END-VERB Constructs, for an explanation of whyNEXT SENTENCEwas necessary.
Programs coded for 1985 (and beyond) standards don’t need it, instead using the explicit scope-terminatorEND-IFto inform the compiler where <imperative-statement-2> (or <imperative-statement-1> if there is noELSEclause coded) ends. New GnuCOBOL programs should be coded to use theEND-IFscope terminator forIFstatements. See Use of VERB/END-VERB Constructs, for additional information.
INITIALIZE|INITIALISE identifier-1...
~~~~~~~~~~ ~~~~~~~~~~
[ WITH FILLER ]
~~~~~~
[ { category-name-1 } TO VALUE ]
{ ALL } ~~~~~
~~~
[ THEN REPLACING { category-name-2 DATA BY
~~~~~~~~~ ~~
[ LENGTH OF ] { literal-1 } }... ]
~~~~~~ { identifier-1 }
[ THEN TO DEFAULT ]
~~~~~~~ DATAOFTHENTOandWITHare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. INITIALIZEandINITIALISEare interchangeable. WITH FILLERREPLACINGandDEFAULTclauses are meaningful only if <identifier-1> is a group item. They are accepted if it’s an elementary item, but will serve no purpose. TheVALUEclause is meaningful in both cases. ALPHABETIC ThePICTURE(see PICTURE) of the data item only containsAsymbols.
ALPHANUMERIC ThePICTUREof the data item contains onlyXor a combination ofAand9symbols.
ALPHANUMERIC-EDITED ThePICTUREof the data item contains onlyXor a combination ofAand9symbols plus at least oneB0(zero) or/symbol.
NUMERIC The data item is one that is described with a picture lessUSAGE(see USAGE) or has aPICTUREcomposed of nothing butP9SandVsymbols.
NUMERIC-EDITED ThePICTUREof the data item contains nothing but the symbol9and at least one of the editing symbols$+-CRDB.,*orZ
NATIONAL The data item is one containing nothing but theNsymbol.
NATIONAL-EDITED The data item contains nothing butNB/and0symbols.
INITIALIZEstatement, a list of initialized fields referred to as the field list in the remainder of this section, will include: REDEFINES(see REDEFINES) clause in their descriptions. REDEFINESclause in its definition nor belongs to a group item subordinate to <identifier-1> which contains aREDEFINESclause in its definition. WITH FILLER MOVE(see MOVE) statement to that effect had been coded. The rules for initialization are as follows: VALUE VALUEclause is specified on theINITIALIZEstatement, each qualifying member of the field list having a compile-timeVALUE(see VALUE) specified in it’s definition will be initialized to that value. Field list members withVALUEclauses will qualify for this treatment as follows: ALLkeyword was specified on theVALUEclause, all members of the field list withVALUEclauses will qualify. ALL only those members of the field list withVALUEclauses that also meet the criteria set down for the specified <category-name> (see the list above) will qualify. VALUEinitialization to multiple <category-name-1> values, you will need to use multipleINITIALIZEstatements. REPLACINGclause is specified on theINITIALIZEstatement, each qualifying member of the field list that was not already initialized by aVALUEclause, if any, will be initialized to the specified <literal-1> or <identifier-1> value. Only those as-yet uninitialized list members meeting the criteria set forth for the specified <category-name-2> will qualify for this initialization.
If you need to applyREPLACINGinitialization to multiple <category-name-2> values, you may repeat the syntax after the reserved wordREPLACING as necessary.
DEFAULTclause is specified, any remaining uninitialized members of the field list will be initialized according to the default for their class (numeric and numeric-edited are initialized to ZERO, all others are initialized to SPACES). INITIALIZEstatement works. The sample code makes use of the COBDUMP program to dump the storage that is (or is not) being initialized. See COBDUMP in GnuCOBOL Sample Programs, for a source and cross-reference listing of the COBDUMP program. IDENTIFICATION DIVISION.
PROGRAM-ID. DemoInitialize.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Item-1.
05 I1-A VALUE ALL '*'.
10 FILLER PIC X(1).
10 I1-A-1 PIC 9(1) VALUE 9.
05 I1-B USAGE BINARY-CHAR.
05 I1-C PIC A(1) VALUE 'C'.
05 I1-D PIC X/X VALUE 'ZZ'.
05 I1-E OCCURS 2 TIMES PIC 9.
PROCEDURE DIVISION.
000-Main.
DISPLAY "MOVE HIGH-VALUES TO Item-1"
PERFORM 100-Init-Item-1
CALL "COBDUMP" USING Item-1
DISPLAY " "
DISPLAY "INITIALIZE Item-1"
INITIALIZE Item-1
CALL "COBDUMP" USING Item-1
PERFORM 100-Init-Item-1
DISPLAY " "
DISPLAY "INITIALIZE Item-1 WITHFILLER"
MOVE HIGH-VALUES TO Item-1
INITIALIZE Item-1 WITHFILLER CALL "COBDUMP" USING Item-1
PERFORM 100-Init-Item-1
DISPLAY " "
DISPLAY "INITIALIZE Item-1 ALL TO VALUE"
MOVE HIGH-VALUES TO Item-1
INITIALIZE Item-1 ALPHANUMERIC TO VALUE
CALL "COBDUMP" USING Item-1
PERFORM 100-Init-Item-1
DISPLAY " "
DISPLAY "INITIALIZE Item-1 REPLACING NUMERIC BY 1"
MOVE HIGH-VALUES TO Item-1
INITIALIZE Item-1 REPLACING NUMERIC BY 1
CALL "COBDUMP" USING Item-1
PERFORM 100-Init-Item-1
DISPLAY " "
STOP RUN
.
100-Init-Item-1.
MOVE HIGH-VALUES TO Item-1
.
When executed, this program produces the following output:
MOVE HIGH-VALUES TO Item-1
<-Addr-> Byte <---------------- Hexadecimal ----------------> <---- Char ---->
======== ==== =============================================== ================
00404058 1 FF FF FF FF FF FF FF FF FF .........
INITIALIZE Item-1
<-Addr-> Byte <---------------- Hexadecimal ----------------> <---- Char ---->
======== ==== =============================================== ================
00404058 1 FF 30 00 20 20 2F 20 30 30 .0. / 00
INITIALIZE Item-1 WITHFILLER<-Addr-> Byte <---------------- Hexadecimal ----------------> <---- Char ---->
======== ==== =============================================== ================
00404058 1 20 30 00 20 20 2F 20 30 30 0. / 00
INITIALIZE Item-1 ALL TO VALUE
<-Addr-> Byte <---------------- Hexadecimal ----------------> <---- Char ---->
======== ==== =============================================== ================
00404058 1 2A 2A FF 43 5A 5A 20 FF FF **.CZZ ..
INITIALIZE Item-1 REPLACING NUMERIC BY 1
<-Addr-> Byte <---------------- Hexadecimal ----------------> <---- Char ---->
======== ==== =============================================== ================
00404058 1 FF 31 01 FF FF FF FF 31 31 .1.....11
INITIATE report-name-1 ~~~~~~~~
RD(see REPORT SECTION) defined for it. FD(see File/Sort-Description) aREPORT <report-name-1>clause exists must be open forOUTPUTorEXTENDat the time theINITIATEstatement is executed. See OPEN, for more information on file open modes. INITIATEstatement will initialize all of the following for each report named on the statement: LINE-COUNTERspecial register (see Special Registers) will be set to 0 PAGE-COUNTERspecial register will be set to 1 INITIATEstatement — that will not occur until the firstGENERATEstatement (see GENERATE) is executed. INSPECT { literal-1 }
~~~~~~~ { identifier-1 }
{ function-reference-1 }
[ TALLYING { identifier-2 FOR { ALL|LEADING|TRAILING { literal-2 } }
~~~~~~~~ ~~~ { ~~~ ~~~~~~~ ~~~~~~~~ { identifier-3 } }
{ CHARACTERS }
~~~~~~~~~~
[ | { AFTER|BEFORE } INITIAL { literal-3 } | ] }... ]
| ~~~~~ ~~~~~~ { identifier-4 } |
[ REPLACING { { { ALL|FIRST|LEADING|TRAILING { literal-4 } }
~~~~~~~~~ { { ~~~ ~~~~~ ~~~~~~~ ~~~~~~~~ { identifier-5 } }
{ CHARACTERS }
{ ~~~~~~~~~~ }
BY { [ ALL ] literal-5 }
~~ { ~~~ }
{ identifier-6 }
[ | { AFTER|BEFORE } INITIAL { literal-6 } | ] }... ]
| ~~~~~ ~~~~~~ { identifier-7 } |
[ CONVERTING { { literal-7 } TO { literal-8 }
~~~~~~~~~~ { identifier-8 } ~~ { identifier-9 }
[ | { AFTER|BEFORE } INITIAL { literal-9 } | ] ]
| ~~~~~ ~~~~~~ { identifier-10 } |
INITIALis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this words has no effect upon the program. CONVERTING TALLYINGorREPLACINGclauses are specified, theCONVERTINGclause cannot be used. TALLYINGandREPLACINGclauses are specified, they must be specified in the order shown. TALLYINGclause may be specified. TALLYINGclause may be specified. CONVERTINGclause replaces one or more individual characters found in the inspect subject with a different character in much the same manner as is possible with theTRANSFORMstatement (see TRANSFORM). REPLACINGclause replaces one or more sub strings located in the inspect subject with a different, but equally-sized replacement sub string. If you need to replace a sub string with another of a different length, consider using either theSUBSTITUTEintrinsic function (see SUBSTITUTE) or theSUBSTITUTE-CASEintrinsic function (see SUBSTITUTE-CASE). TALLYINGclause counts the number of occurrences of one or more strings of characters in the inspect subject. INITIALclauses may be used to limit the range of characters in the inspect subject that theCONVERTINGREPLACINGorTALLYINGinstruction in which they occur will apply. We call this the ’target range’ of the inspect subject. The target range is defined as follows: INITIALclause specified, the target range is the entire inspect subject. BEFOREphrase, anAFTERphrase or both may be specified. They may be specified in any order. AFTERspecification. The ending point will be the last character immediately preceding the sub string identified by theBEFOREspecification. AFTERis specified, the first character position of the target range will be character position #1 of the inspect subject. BEFOREis specified, the last character position of the target range will be the last character position of the inspect subject. TALLYINGclause: INSPECT INSPECT Character-String
TALLYING C-ABC FOR ALL "ABC"
There could be multiple counting instructions specified:
INSPECT Character-String
TALLYING C-ABC FOR ALL "ABC"
C-BCDE FOR ALL "BCDE"
When there are multiple instructions, the one specified first will take priority over the one specified second, (and so forth) as theINSPECTproceeds forward through the inspect subject, character-by-character.
With the above example, if the inspect subject were--ABCDEF----BCDEF-- the final result of the counting would be that C-ABC would be incremented by 1 while C-BCDE would be incremented only once; although the human eye clearly sees two "BCDE" sequences, theINSPECT ... TALLYINGwould only "see" the second — the first would have been processed by the first (higher-priority) counting instruction.
AFTER INITIALand/orBEFORE INITIALclause; the rules for specifying target ranges were covered previously. ALL— identifies every possible target sub string that occurs within the target range. There are three occurrences ofALL 'XX'found inaXXabbXXccXXdd
LEADING— identifies only an occurrence of the target sub string found either at the first character position of the target range or immediately following a previously-found occurrence. There are no occurrences ofLEADING 'XX'found inaXXabbXXccXXdd but there is one occurrence ofLEADING 'a'(the first character).
TRAILING— identifies only an occurrence of the target sub string found either at the very end of the target range or toward the end, followed by nothing but other occurrences. There are no occurrences ofLEADING 'XX'found inaXXabbXXccXXdd but there are two occurrences ofTRAILING 'd'
TheCHARACTERSoption will match any one single character, regardless of what that character is.
INSPECTstatement will not zero-out <identifier-2> at the start of execution of theINSPECT— it is the programmer’s responsibility to ensure that all <identifier-2> data items are properly initialized to the desired starting values prior to execution of theINSPECT REPLACINGclause: INSPECT INSPECT Character-String
REPLACING ALL "ABC" BY "DEF"
There could be multiple replacement instructions:
INSPECT Character-String
REPLACING ALL "ABC" BY "DEF"
ALL "BCDE" BY "WXYZ"
When there are multiple replacement instructions, the one specified first will take priority over the one specified second, (and so forth) as theINSPECTproceeds forward through the inspect subject, character-by-character.
With the above example, if the inspect subject were--ABCDEF----BCDEF-- the final result of the replacement would be--DEFDEF----WXYZF--
AFTER INITIALand/orBEFORE INITIALclause; the rules for specifying target ranges were covered previously. BYkeyword, may be defined as a literal value (figurative constants are allowed) or by the contents of an identifier. If the target sub string is specified as a figurative constant, it will be assumed to have a length of one (1) character. The keywords before the literal or identifier control how many target sub strings could be identified from that replacement instruction, as follows: ALL— identifies every possible target sub string that occurs within the target range. There are three occurrences ofALL 'XX'found inaXXabbXXccXXdd
FIRST— the first occurrence of the target sub string found within the target range. TheFIRST 'XX'found inaXXabbXXccXXddwould be the one found between the "a" and "b" characters.
LEADING— an occurrence of the target sub string found either at the first character position of the target range or immediately following a previously-found occurrence. There are no occurrences ofLEADING 'XX'found inaXXabbXXccXXdd but there is one occurrence ofLEADING 'a'(the first character).
TRAILING— an occurrence of the target sub string found either at the very end of the target range or toward the end, followed by nothing but other occurrences. There are no occurrences ofLEADING 'XX'found inaXXabbXXccXXdd but there are two occurrences ofTRAILING 'd'
TheCHARACTERSoption will match any one single character. When you use this option, the replacement sub string (see the next item) must be exactly one character in length.
BYkeyword. They too may be specified as a literal, either with or without anALLprefix (again, figurative constants are allowed) or the value of an identifier. If a figurative constant is coded, theALLkeyword will be assumed, even if it wasn’t specified. Literals withoutALLwill either be truncated or padded with spaces on the right to match the length of the target sub string. Literals withALLor figurative constants will be repeated as necessary to match the length of the target sub string. Identifiers specified as replacement sub strings must be defined with a length equal to that of the target sub string. REPLACINGandTALLYINGare specified: INSPECTstatement will make a single pass through the sequence of characters comprising the inspect subject. As the pointer to the current inspect target character reaches a point where it falls within the explicit or implicit target ranges specified on the operational instructions of the two clauses, the actions specified by those instructions will become eligible to be taken. As the character pointer reaches a point where it falls past the end of target ranges, the instructions belonging to those target ranges will become disabled. REPLACINGand/orTALLYINGoperational instructions active. Only one of theTALLYINGand one of theREPLACINGinstructions (if any) can be executed for any one character pointer position. In each case, it will be the first of the instructions in each category that produces a match with it’s target string specification. TALLYINGand aREPLACINGinstruction have been selected for execution, theTALLYINGinstruction will be executed first. This guarantees thatTALLYINGwill compute occurrences based upon the initial value of the inspect subject before any replacements occur. CONVERTINGclause: CONVERTINGclause performs a series of single-character substitutions against a data item in much the same manner as is possible with theTRANSFORMstatement (see TRANSFORM). TALLYINGandREPLACINGclauses, both of which may have multiple operations specified, there may be only oneCONVERTINGoperation perINSPECT MERGE sort-file-1
~~~~~
{ ON { ASCENDING } KEY identifier-1... }...
{ ~~~~~~~~~ }
{ DESCENDING }
~~~~~~~~~~
[ WITH DUPLICATES IN ORDER ]
~~~~~~~~~~
[ COLLATING SEQUENCE IS alphabet-name-1 ]
~~~~~~~~~
USING file-name-1 file-name-2...
~~~~~
{ OUTPUT PROCEDURE IS procedure-name-1 }
{ ~~~~~~ ~~~~~~~~~ }
{ [ THRU|THROUGH procedure-name-2 ] }
{ ~~~~ ~~~~~~~ }
{ GIVING file-name-3... }
{ ~~~~~~ }
TheDUPLICATES
INISKEYONORDERSEQUENCEandWITHare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. THRUandTHROUGHare interchangeable. WITH DUPLICATES IN ORDERclause is specified, even if it isn’t. While any COBOL implementation’s sort or merge facilities guarantee that records with duplicate key values will be in proper sequence with regard to other records with different key values, they generally make no promises as to the resulting relative sequence of records having duplicate key values with one another.
Some COBOL implementations provide this optional clause to force their sort and merge facilities to retain duplicate key-value records in their original input sequence, relative to one another.
MERGEstatement must be defined using a sort description SD(see File/Sort-Description)). This file is referred to in the remainder of this discussion as the "merge work file". ORGANIZATION LINE SEQUENTIAL(see ORGANIZATION LINE SEQUENTIAL) orORGANIZATION SEQUENTIAL(see ORGANIZATION SEQUENTIAL) files. These files must be defined using a file description FD(see File/Sort-Description)). PICTURE(see PICTURE) of fields,USAGE(see USAGE) of fields, size of fields and location of fields within the records should match field-by-field across all files, at least as far as theKEYfields are concerned. MERGEstatement is to define the records of all files involved as simple elementary items of the form01 record-name PIC X(n).where n is the record size. The only file where records are actually described in detail would then be <sort-file-1>. USINGclause: MERGEis executed. MERGEstatement’sKEY SAME RECORD AREA(see SAME RECORD AREA),SAME SORT AREAorSAME SORT-MERGE AREAstatement. MERGEstatement begins execution, the first record in each of theUSING MERGEstatement executes, the current record from each of theUSINGfiles is examined and compared to each other according to the rules set forth by theKEYclause and the alphabet (see Alphabet-Name-Clause) specified on theCOLLATING SEQUENCE GIVING GIVINGis specified, none of the <file-name-3> files can be open at the time theMERGEstatement is executed. OUTPUT PROCEDUREclause will be invoked as if by a proceduralPERFORM(see Procedural PERFORM) statement with noVARYINGTIMESorUNTILoptions specified. Merged records may be read from the merge work file — one at a time — within the output procedure using theRETURN(see RETURN) statement. AGO TOstatement (see GO TO) that transfers control out of the output procedure will terminate theMERGEstatement but allows the program to continue executing from the point where theGO TOstatement transferred control to. Once an output procedure has been "aborted" using aGO TOit cannot be resumed, and the contents of the merge work file are lost. You may, however, re-execute theMERGEstatement itself. USING AGO TOstatement TO PREMATURELY TERMINATE A MERGE, OR RE-STARTING A PREVIOUSLY-CANCELLED MERGE IS NOT CONSIDERED GOOD PROGRAMMING STYLE AND SHOULD BE AVOIDED.
An output procedure should be terminated in the same way a proceduralPERFORMstatement would be. Usually, this action will be taken once theRETURNstatement indicates that all records in the merge work file have been processed, but termination could occur at any time — via anEXITstatement (see EXIT) — if required.
Neither a file-basedSORTstatement (see File-Based SORT) nor anotherMERGEstatement may be executed within the scope of the procedures comprising the output procedure unless those statements utilize a different sort or merge work file.
MERGEstatement itself — is complete. MOVE { literal-1 } TO identifier-2...
~~~~ { identifier-1 } ~~ MOVEstatement will replace the contents of one or more receiving data items (<identifier-2>) with a new value — the one specified by <literal-1> or <identifier-1>. MOVEinvolving numeric data will perform any necessary format conversions that might be necessary due to differingUSAGE(see USAGE) specifications. MOVE CORRESPONDING identifier-1 TO identifier-2... ~~~~ ~~~~ ~~
CORRESPONDINGmay be abbreviated asCORR MOVE CORRESPONDINGon those matches will be as if a series of individualMOVE were done — one for each match. MULTIPLY { literal-1 } BY { identifier-2
~~~~~~~~ { identifier-1 } ~~
[ ROUNDED [ MODE IS { AWAY-FROM-ZERO } ] ] }...
~~~~~~~ ~~~~ { ~~~~~~~~~~~~~~ }
{ NEAREST-AWAY-FROM-ZERO }
{ ~~~~~~~~~~~~~~~~~~~~~~ }
{ NEAREST-EVEN }
{ ~~~~~~~~~~~~ }
{ NEAREST-TOWARD-ZERO }
{ ~~~~~~~~~~~~~~~~~~~ }
{ PROHIBITED }
{ ~~~~~~~~~~ }
{ TOWARD-GREATER }
{ ~~~~~~~~~~~~~~ }
{ TOWARD-LESSER }
{ ~~~~~~~~~~~~~ }
{ TRUNCATION }
~~~~~~~~~~
[ ON SIZE ERROR imperative-statement-1 ]
~~~~ ~~~~~
[ NOT ON SIZE ERROR imperative-statement-2 ]
~~~ ~~~~ ~~~~~
[ END-DIVIDE ]
~~~~~~~~~~ ISandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. ROUNDED(see ROUNDED) clause available to each <identifier-2> will control how non-integer results will be saved. ON SIZE ERRORandNOT ON SIZE ERRORclauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-2> with an insufficient number of digit positions available to the left of any implied decimal point. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information. MULTIPLY { literal-1 } BY { literal-2 } GIVING { identifier-3
~~~~~~~~ { identifier-1 } ~~ { identifier-2 } ~~~~~~
[ ROUNDED [ MODE IS { AWAY-FROM-ZERO } ] ] }...
~~~~~~~ ~~~~ { ~~~~~~~~~~~~~~ }
{ NEAREST-AWAY-FROM-ZERO }
{ ~~~~~~~~~~~~~~~~~~~~~~ }
{ NEAREST-EVEN }
{ ~~~~~~~~~~~~ }
{ NEAREST-TOWARD-ZERO }
{ ~~~~~~~~~~~~~~~~~~~ }
{ PROHIBITED }
{ ~~~~~~~~~~ }
{ TOWARD-GREATER }
{ ~~~~~~~~~~~~~~ }
{ TOWARD-LESSER }
{ ~~~~~~~~~~~~~ }
{ TRUNCATION }
~~~~~~~~~~
[ ON SIZE ERROR imperative-statement-1 ]
~~~~ ~~~~~
[ NOT ON SIZE ERROR imperative-statement-2 ]
~~~ ~~~~ ~~~~~
[ END-DIVIDE ]
~~~~~~~~~~ ISandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. ROUNDED(see ROUNDED) clause available to each <identifier-2> will control how non-integer results will be saved. ON SIZE ERRORandNOT ON SIZE ERRORclauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-2> with an insufficient number of digit positions available to the left of any implied decimal point. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information. OPEN { { INPUT } [ SHARING WITH { ALL OTHER } ] file-name-1
~~~~ { ~~~~~ } ~~~~~~~ { ~~~ }
{ OUTPUT } { NO OTHER }
{ ~~~~~~ } { ~~ }
{ I-O } { READ ONLY }
{ ~~~ } ~~~~ ~~~~
{ EXTEND }
~~~~~~
[ { REVERSED } ] }...
{ ~~~~~~~~ }
{ WITH { NO REWIND } }
{ { ~~ ~~~~~~ } }
{ { LOCK } }
~~~~ TheNO REWIND
OTHERandWITHare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. SHARINGandWITH LOCKclauses may not both be specified in the sameOPENstatement. ACLOSEstatement (see CLOSE)
ADELETEstatement (see DELETE)
AREADstatement (see READ)
AREWRITEstatement (see REWRITE)
ASTARTstatement (see START)
AnUNLOCKstatement (see UNLOCK)
AWRITEstatement (see WRITE)
DECLARATIVES(see DECLARATIVES) or an error procedure established using theCBL_ERROR_PROCbuilt-in system subroutine (see CBL_ERROR_PROC) built-in subroutine. When either of these trap routines exit, however, the GnuCOBOL runtime system will still terminate the program after your trap logic is executed. Ultimately, you cannot recover from an open failure. INPUTYou may only read the existing contents of the file — only theCLOSEREADSTARTandUNLOCKstatements will be allowed. This enforcement takes place at execution time, not compilation time.
OUTPUTYou may only write new content (which will completely replace any previous file contents) to the file — only theCLOSEUNLOCKandWRITEstatements will be allowed. This enforcement takes place at execution time, not compilation time.
I-OYou may perform any operation you wish against the file — all file I/O statements will be allowed.
EXTENDYou may only write new content (which will be appended after the previously existing file contents) to the file — only theCLOSEUNLOCKandWRITEstatements will be allowed. This enforcement takes place at execution time, not compilation time. You cannot extend an empty file; this will not generate a runtime error, but no output will appear in the file.
SHARING WITH LOCK PERFORM procedure-name-1 [ THRU|THROUGH procedure-name-2 ]
~~~~~~~ ~~~~ ~~~~~~~
[ { [ WITH TEST { BEFORE } ] { VARYING-Clause } } ]
{ ~~~~ { ~~~~~~ } { UNTIL conditional-expression-1 } }
{ { AFTER } ~~~~~ }
{ ~~~~~ }
{ UNTIL EXIT|FOREVER }
{ ~~~~~ ~~~~ ~~~~~~~ }
{ { literal-1 } TIMES }
{ { identifier-1 } ~~~~~ } WITHis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. THRUandTHROUGHare interchangeable. FOREVERandUNTIL EXITare interchangeable. PERFORMstatement. If <procedure-name-2> is specified, it must follow <procedure-name-1> in the program’s source code. UNTIL FOREVERoption will repeatedly execute the code within the perform scope with no conditions defined for termination of the repetition — it will be up to the programmer to include anEXIT SECTIONstatement (see EXIT) orEXIT PARAGRAPHstatement within the procedure(s) being performed that will break out of the loop. TIMESoption will repeat the execution of the code within the perform scope a fixed number of times. When thePERFORMstatement begins execution, an internal repeat counter (not accessible to the programmer) will be set to the value of <literal-1> or the value within <identifier-1>. If the counter has a value greater than zero, the statement(s) within thePERFORMscope will be executed, after which the counter will be decremented by 1 with each repetition. Once that counter reaches zero, repetition will cease and control will fall into the next statement following thePERFORM
If the <identifier-1> option was used, altering the value of that data item within the perform scope will not affect the repetition count.
UNTIL <conditional-expression-1>option will repeat the code within the perform scope until the specified conditional expression evaluates to a TRUE value. WITH TEST The default, if this clause is absent, isWITH TEST BEFORE
This clause may not be coded when theTIMESclause is used.
UNTILclause. See VARYING, for the details. PERFORM
~~~~~~~
[ { [ WITH TEST { BEFORE } ] { VARYING-Clause } } ]
{ ~~~~ { ~~~~~~ } { UNTIL conditional-expression-1 } }
{ { AFTER } ~~~~~ }
{ ~~~~~ }
{ UNTIL EXIT|FOREVER }
{ ~~~~~ ~~~~ ~~~~~~~ }
{ { literal-1 } TIMES }
{ { identifier-1 } ~~~~~ }
imperative-statement-1
[ END-PERFORM ]
~~~~~~~~~~~ VARYING identifier-2 FROM { literal-2 } [ BY { literal-3 } ]
~~~~~~~ ~~~~ { identifier-3 } ~~ { identifier-4 }
[ UNTIL conditional-expression-1 ]
~~~~~
[ AFTER identifier-5 FROM { literal-4 } [ BY { literal-5 } ]
~~~~~ ~~~~ { identifier-6 } ~~ { identifier-7 }
[ UNTIL conditional-expression-2 ] ]...
~~~~~ VARYINGportion of the clause: PERFORMbegins execution, theFROMvalue will be moved to <identifier>. PERFORMspecifies or impliesWITH TEST BEFORE <conditional-expression-1> will be evaluated and processing of thePERFORMwill halt if the expression evaluates to TRUE. IfWITH TEST BEFOREwas not specified or implied, or if the conditional expression evaluated to FALSE, processing proceeds with step (C). GO TOexecuted within the perform scope transfers control to a point outside the perform scope, processing of thePERFORMwill halt. EXIT PERFORM CYCLEstatement (see EXIT), or… EXIT PARAGRAPHstatement orEXIT SECTIONstatement when there is only one paragraph (or section) in the perform scope ( this option only applies to a proceduralPERFORM Control will return back to thePERFORM where — ifWITH TEST AFTERwas specified — <conditional-expression-1> will be evaluated and processing of thePERFORMwill halt if the expression evaluates to TRUE. IfWITH TEST AFTERwas not specified, or if the conditional expression evaluated to FALSE, processing continues with the next step.
BYvalue, if any, will be added to <identifier-2>. If noBYis specified, <identifier-2> will be unaffected. You are always free to modify the value of <identifier-2> yourself within the perform scope. AFTERspecified. Those that do, however, are establishing a loop-within-a-loop situation where the process described above in steps (A) through (F) will take place from theAFTER and those six processing steps actually replace step (C) of theVARYING This "nesting" process can continue indefinitely, with each additionalAFTER This is the point where an example should really help you see this at work. Observe the following code which defines a two-dimensional (3 row by 4 column) table and a pair of numeric data items to be used to subscript references to each element of the table:
01 PERFORM-DEMO.
05 PD-ROW OCCURS 3 TIMES.
10 PD-COL OCCURS 4 TIMES
15 PD PIC X(1).
01 PD-Col-No PIC 9 COMP.
01 PD-Row-No PIC 9 COMP.
Let’s say the 3x4 "grid" defined by the above structure has these values:
A B C D E F G H I J K L
This code will displayABCDEFGHIJKLon the console output window:
PERFORM WITH TEST AFTER
VARYING PD-Row-No FROM 1 BY 1 UNTIL PD-Row-No = 3
AFTER PD-Col-No FROM 1 BY 1 UNTIL PD-Col-No = 4
DISPLAY PD (PD-Row-No, PD-Col-No) WITH NO ADVANCING
END-PERFORM
While this code will displayAEIBFJCGKDHLon the console output window:
PERFORM WITH TEST AFTER
VARYING PD-Col-No FROM 1 BY 1 UNTIL PD-Col-No = 4
AFTER PD-Row-No FROM 1 BY 1 UNTIL PD-Row-No = 3
DISPLAY PD (PD-Row-No, PD-Col-No) WITH NO ADVANCING
END-PERFORM
While we’re looking at sample code, this code displaysABCEFG
PERFORM
VARYING PD-Row-No FROM 1 BY 1 UNTIL PD-Row-No = 3
AFTER PD-Col-No FROM 1 BY 1 UNTIL PD-Col-No = 4
DISPLAY PD (PD-Row-No, PD-Col-No) WITH NO ADVANCING
END-PERFORM
By removing theWITH TESTclause, the statement is now assumingWITH TEST BEFORE Since testing now happens before theDISPLAYstatement gets executed, when PD-Row-No is 3 and PD-Col-No is 4 theDISPLAYstatement won’t be executed.
Most COBOL programmers, when usingWITH TEST BEFOREexplicitly or implicitly have developed the habit of using ">" rather than "=" onUNTILclauses. This would make the sample code:
PERFORM
VARYING PD-Row-No FROM 1 BY 1 UNTIL PD-Row-No > 3
AFTER PD-Col-No FROM 1 BY 1 UNTIL PD-Col-No > 4
DISPLAY PD (PD-Row-No, PD-Col-No) WITH NO ADVANCING
END-PERFORM
With this change,ABCDEFGHIJKLis once again displayed.
READ file-name-1 [ { NEXT|PREVIOUS } ] RECORD [ INTO identifier-1 ]
~~~~ { ~~~~ ~~~~~~~~ } ~~~~
[ { IGNORING LOCK } ]
{ ~~~~~~~~ ~~~~ }
{ WITH [ NO ] LOCK }
{ ~~ ~~~~ }
{ WITH KEPT LOCK }
{ ~~~~ ~~~~ }
{ WITH IGNORE LOCK }
{ ~~~~~~ ~~~~ }
{ WITH WAIT }
~~~~
[ AT END imperative-statement-1 ]
~~~
[ NOT AT END imperative-statement-2 ]
~~~ ~~~
[ END-READ ]
~~~~~~~~ ATRECORDandWITHare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. FD(see File/Sort-Description), not anSD INPUT(see File OPEN Modes) orI-O ORGANIZATION RELATIVE(see ORGANIZATION RELATIVE) orORGANIZATION INDEXED(see ORGANIZATION INDEXED) file with anACCESS MODE RANDOM this statement cannot be used. ACCESS MODE SEQUENTIAL this is the only format of theREADstatement that is available. ORGANIZATION RELATIVE(see ORGANIZATION RELATIVE) orORGANIZATION INDEXED(see ORGANIZATION INDEXED) file withACCESS MODE DYNAMIC this statement as well as a randomREAD(see Random READ) may be used. NEXT PREVIOUSoption is available only forORGANIZATION INDEXEDfiles. READ <file-name-1>is perfectly legal according to both READ formats. For that reason, whenACCESS MODE DYNAMIChas been specified and you want to tell the GnuCOBOL compiler that this minimal statement should be treated as a sequentialREAD you must add eitherNEXTorPREVIOUSto the statement (otherwise it will be treated as a randomREAD. NEXTorPREVIOUSoption. The newly-retrieved record data will be saved into the 01-level record structure(s) that immediately follow the file’sFD If the optionalINTO ORGANIZATION RELATIVEfile has been successfully read, the file’sRELATIVE KEY(see ORGANIZATION RELATIVE) field will be automatically populated with the relative record number (ordinal occurrence number) of the record in the file. LOCKoptions may be used to manually control access to the retrieved record by other programs while this program is running. See Record Locking, to review the various record locking behaviours. AT ENDclause, if coded, is used to detect and react to the failure of an attempt to retrieve another record from the file due to an end-of-file (i.e. no more records) condition. NOT AT ENDclause, if coded, will check checking for a file status value of 00. See File Status Codes, for additional information. READ file-name-1 RECORD [ INTO identifier-1 ]
~~~~ ~~~~
[ { IGNORING LOCK } ]
{ ~~~~~~~~ ~~~~ }
{ WITH [ NO ] LOCK }
{ ~~ ~~~~ }
{ WITH KEPT LOCK }
{ ~~~~ ~~~~ }
{ WITH IGNORE LOCK }
{ ~~~~~~ ~~~~ }
{ WITH WAIT }
~~~~
[ KEY IS identifier-2 ]
~~~
[ INVALID KEY imperative-statement-1 ]
~~~~~~~
[ NOT INVALID KEY imperative-statement-2 ]
~~~ ~~~~~~~
[ END-READ ]
~~~~~~~~ ISKEY(on theINVALIDandNOT INVALIDclauses),RECORDandWITHare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. FD(see File/Sort-Description), not anSD INPUT(see File OPEN Modes) orI-O ACCESS MODEof <file-name-1> isSEQUENTIAL or theORGANIZATIONof the file is any form of sequential, this format of theREADstatement cannot be used. ACCESS MODEof <file-name-1> isRANDOM this is the only format of theREADstatement that is available. ORGANIZATION RELATIVE(see ORGANIZATION RELATIVE) orORGANIZATION INDEXED(see ORGANIZATION INDEXED) file withACCESS MODE DYNAMIC this statement as well as a sequentialREAD(see Sequential READ) may be used. READ <file-name-1>is perfectly legal according to both READ formats. For that reason, whenACCESS MODE DYNAMIChas been specified and you want to tell the GnuCOBOL compiler that this minimal statement should be treated as a randomREAD you must omit theNEXTorPREVIOUSavailable to the sequential format of theREADstatement to ensure the statement will be treated as a randomREAD KEY ORGANIZATION RELATIVEfile, the contents of the field declared as the file’sRELATIVE KEYwill be used to identify a record, otherwise… ORGANIZATION INDEXEDfile, the contents of the field declared as the file’sRECORD KEYwill be used to identify a record. KEYclause is specified, and… ORGANIZATION RELATIVEfile, the contents of <identifier-2> will be used as the relative record number of the record to be accessed — <identifier-2> need not be theRELATIVE KEY(see ORGANIZATION RELATIVE) field of the file (although it could be if you wish). ORGANIZATION INDEXEDfile, <identifier-2> must be theRECORD KEY(see ORGANIZATION INDEXED) or one of the file’sALTERNATE RECORD KEYfields (if any) — the current contents of that field will identify the record to be accessed. If an alternate record key is used, and that key allows duplicate values, the record accessed will be the first one having that key value. FD If the optionalINTO ORGANIZATION RELATIVEfile has been successfully read, the file’sRELATIVE KEY(see ORGANIZATION RELATIVE) field will be automatically populated with the relative record number (ordinal occurrence number) of the record in the file. LOCKoptions may be used to manually control access to the retrieved record by other programs while this program is running. See Record Locking, to review the various record locking behaviours. INVALID KEYandNOT INVALID KEYclauses may be used to detect and react to the failure or success, respectively, by detecting non-zero (typically 23 = key not found = record not found) and 00 file status codes, respectively. See File Status Codes, for additional information. READY TRACE ~~~~~ ~~~~~
-ftraceswitch RESET TRACEstatement (see RESET TRACE). RELEASE record-name-1 [ FROM { literal-1 } ]
~~~~~~~ ~~~~ { identifier-1 } INPUT PROCEDUREof a file-basedSORTstatement (see File-Based SORT). SD(see File/Sort-Description)) of the sort work file being processed by the current sort. FROM RESET TRACE ~~~~~ ~~~~~
READY TRACEstatement (see READY TRACE) can be used to turn tracing on. -ftraceswitch RETURN sort-file-name-1 RECORD
~~~~~~
[ INTO identifier-1 ]
~~~~
AT END imperative-statement-1
~~~
[ NOT AT END imperative-statement-2 ]
~~~ ~~~
[ END-RETURN ]
~~~~~~~~~~
ATandRECORDare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. RETURNstatement is valid only within theOUTPUT PROCEDUREof a file-basedSORT(see File-Based SORT) or aMERGEstatement (see MERGE) statement. SD(see File/Sort-Description), not anFD RETURNwill retrieve the next available record from <sort-file-name-1>. The newly-retrieved record data will be saved into the 01-level record structure(s) that immediately follow the file’s SD. If the optionalINTO AT ENDclause is used to detect and react to the failure of an attempt to retrieve another record from the file due to an end-of-file (i.e. no more records) condition. NOT AT ENDclause, if coded, will check checking for a file status value of 00. See File Status Codes, for additional information. REWRITE record-name-1
~~~~~~~
[ FROM { literal-1 } ]
~~~~ { identifier-1 }
[ WITH [ NO ] LOCK ]
~~ ~~~~
[ INVALID KEY imperative-statement-1 ]
~~~~~~~
[ NOT INVALID KEY imperative-statement-2 ]
~~~ ~~~~~~~
[ END-REWRITE ]
~~~~~~~~~~~ KEYandWITHare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. FD(see File/Sort-Description)) of a file that is currently open forI-O(see File OPEN Modes). FROM ORGANIZATION LINE SEQUENTIAL(see ORGANIZATION LINE SEQUENTIAL) files. COMMIT(see COMMIT) orUNLOCKstatement (see UNLOCK) is issued or that file is closed. ORGANIZATION SEQUENTIAL(see ORGANIZATION SEQUENTIAL): READ(see READ) of the file. FDof the file contains theRECORD CONTAINSorRECORD IS VARYINGclause, and that clause allows the record size to vary, the size of <record-name-1> cannot be altered. ORGANIZATION RELATIVE(see ORGANIZATION RELATIVE) orORGANIZATION INDEXED(see ORGANIZATION INDEXED): ACCESS MODE SEQUENTIAL the record to be rewritten will be the one retrieved by the most-recently executedREADof the file. If the file hasACCESS MODE RANDOMorACCESS MODE DYNAMIC noREADis required before a record may be rewritten — theRELATIVE KEYorRECORD KEYdefinition for the file, respectively, will specify the record to be updated. FDof the file contains theRECORD CONTAINSorRECORD IS VARYINGclause, and that clause allows the record size to vary, the size can be altered. LOCKoptions may be used to manually control access to the re-written record by other programs while this program is running. See Record Locking, to review the various record locking behaviours. INVALID KEYandNOT INVALID KEYclauses may be used to detect and react to the failure or success, respectively, by detecting non-zero (typically 23 = key not found = record not found) and 00 file status codes, respectively. See File Status Codes, for additional information. ROLLBACK ~~~~~~~~
SEARCH table-name-1
~~~~~~
[ VARYING index-name-1 ]
~~~~~~~
[ AT END imperative-statement-1 ]
~~~
{ WHEN conditional-expression-1 imperative-statement-2 }...
~~~~
[ END-SEARCH ]
~~~~~~~~~~ ATis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. SEARCHstatement is executed, the current value of the search index data item will define the starting position in the table where the searching process will begin. Typically, one initializes that index to a value of 1 before starting theSEARCHviaSET <search-index> TO 1 WHENclause(s) should involve a data element within the table, subscripted using the search index. WHENclause whose <conditional-expression-n> evaluated to TRUE will be executed; after that, the search will be considered complete and control will fall into the first executable statement following theSEARCH AT END SEARCH ALL table-name-1
~~~~~~ ~~~
[ AT END imperative-statement-1 ]
~~~
WHEN conditional-expression-1 imperative-statement-2
~~~~
[ END-SEARCH ]
~~~~~~~~~~ ATis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. SEARCH ALL OCCURSclause of <table-name-1> must contain the following elements: INDEXED BY ASCENDING KEY KEYclauses doesn’t mean the data is actually in that sequence in the table — the actual sequence of the data must agree with the KEY clause(s)! A table-basedSORT(see Table SORT) can prove very useful in this regard. KEYfield values. If the table has multipleKEYdefinitions, then no two records in the table may have the same combination ofKEYfield values. SEARCH ALL If rules (B) and/or (C) are violated, there will be no message issued by the compiler, but the run-time results of aSEARCH ALLagainst the table will probably be incorrect. KEYfield(s), using the search index (the table’sINDEXED BYindex name) as a subscript. WHEN SEARCH ALL SEARCH ALL If there is noAT ENDclause coded, control simply falls into the next statement following theSEARCH ALL SEARCHandSEARCH ALLstatements as follows: Here’s a more practical view of the difference. Let’s say that a table has 1,000 entries in it. With a sequential search, on average, you’ll have to check 500 of them to find an entry and you’ll have to look at all 1,000 of them to find that an entry doesn’t exist.
With a binary search, express the number of entries as a binary number (1,000 = 1111101000), count the number of digits in the result (which is, essentially, what a logarithm is, when rounded up to the next integer — the number of digits a decimal number would have if expressed in the logarithm’s number base). In this case, we end up with 10 — THAT is the worst-case number of tests required to find an entry or to identify that it doesn’t exist. That’s quite an improvement!
SET ENVIRONMENT { literal-1 } TO { literal-2 }
~~~ ~~~~~~~~~~~ { identifier-1 } ~~ { identifier-2 } This is a much simpler and more readable means of setting environment variables than by using theDISPLAY UPON ENVIRONMENT-NAMEstatement (see DISPLAY UPON ENVIRONMENT-NAME). For example, these two code sequences produce identical results:
DISPLAY "VARNAME" UPON ENVIRONMENT-NAME DISPLAY "VALUE" UPON ENVIRONMENT-VALUE SET ENVIRONMENT "VARNAME" TO "VALUE"
SET program-pointer-1 TO ENTRY { literal-1 }
~~~ ~~ ~~~~~ { identifier-1 } SETstatement. USAGE(see USAGE) of <program-pointer-1> must bePROGRAM-POINTER PROGRAM-IDof a subroutine orFUNCTION-IDof a user-defined function) or an alternate entry-point defined via anENTRYstatement within a subprogram. PROGRAM-POINTER at work, see the discussions of theCBL_ERROR_PROCbuilt-in system subroutine (see CBL_ERROR_PROC) andCBL_EXIT_PROCbuilt-in system subroutine (see CBL_EXIT_PROC). SET [ ADDRESS OF ] { pointer-name-1 }...
~~~ ~~~~~~~ ~~ { identifier-1 }
TO [ ADDRESS OF ] { pointer-name-2 }
~~ ~~~~~~~ ~~ { identifier-2 }
ADDRESS OF ADDRESS OFclause is used after theTO this statement will be identifying the address of <identifier-2> as the address to be assigned to <identifier-1> or stored in <pointer-name-1>. ADDRESS OFclause is absent after theTO the contents of <pointer-name-2> will serve as the address to be assigned. SET index-name-1 TO { literal-1 }
~~~ ~~ { identifier-2 }
USAGE(see USAGE) of <index-name-1> should beINDEX or <index-name-1> must be identified in a tableINDEXED BYclause. SET identifier-1 { UP } BY [ LENGTH OF ] { literal-1 }
~~~ { ~~ } ~~ ~~~~~~ ~~ { identifier-2 }
{ DOWN }
~~~~ USAGE(see USAGE) of <identifier-1> must beINDEXPOINTERorPROGRAM-POINTER USAGE INDEXdata item is to increment it’s valueUPorDOWNby 1, since an index is usually being used to sequentially walk through the elements of a table. SET condition-name-1... TO { TRUE }
~~~ ~~ { ~~~~ }
{ FALSE }
~~~~~ TRUE the value assigned to each parent data item will be the first value specified on the condition name’sVALUEclause. FALSE the value assigned to each parent data item will be the value specified for theFALSEclause of the condition name’s definition; if any <condition-name-1> occurrence lacks aFALSEclause, theSETstatement will be rejected by the compiler. SET mnemonic-name-1... TO { ON }
~~~ ~~ { ~~ }
{ OFF }
~~~ SPECIAL-NAMES(see SPECIAL-NAMES) paragraph. IFstatement (see IF) and a Switch-Status Condition. See Switch-Status Conditions, for more information. SET identifier-1 ATTRIBUTE { { BELL } { ON }...
~~~ ~~~~~~~~~ { ~~~~ } { ~~ }
{ BLINK } { OFF }
{ ~~~~~ } ~~~
{ HIGHLIGHT }
{ ~~~~~~~~~ }
{ LEFTLINE }
{ ~~~~~~~~ }
{ LOWLIGHT }
{ ~~~~~~~~ }
{ OVERLINE }
{ ~~~~~~~~ }
{ REVERSE-VIDEO }
{ ~~~~~~~~~~~~~ }
{ UNDERLINE }
~~~~~~~~~
SORT sort-file-1
~~~~
{ ON { ASCENDING } KEY identifier-1... }...
{ ~~~~~~~~~ }
{ DESCENDING }
~~~~~~~~~~
[ WITH DUPLICATES IN ORDER ]
~~~~~~~~~~
[ COLLATING SEQUENCE IS alphabet-name-1 ]
~~~~~~~~~
{ INPUT PROCEDURE IS procedure-name-1 }
{ ~~~~~~ ~~~~~~~~~ }
{ [ THRU|THROUGH procedure-name-2 ] }
{ ~~~~ ~~~~~~~ }
{ USING file-name-1... }
~~~~~
{ OUTPUT PROCEDURE IS procedure-name-3 }
{ ~~~~~~ ~~~~~~~~~ }
{ [ THRU|THROUGH procedure-name-4 ] }
{ ~~~~ ~~~~~~~ }
{ GIVING file-name-3... }
~~~~~~
TheDUPLICATES
INISKEYONORDERSEQUENCEandWITHare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. THRUandTHROUGHare interchangeable. WITH DUPLICATES IN ORDERclause is specified, even if it isn’t. While any COBOL implementation’s sort or merge facilities guarantee that records with duplicate key values will be in proper sequence with regard to other records with different key values, they generally make no promises as to the resulting relative sequence of records having duplicate key values with one another.
Some COBOL implementations provide this optional clause to force their sort and merge facilities to retain duplicate key-value records in their original input sequence, relative to one another.
SORTstatement must be defined using a sort description SD(see File/Sort-Description)). This file is referred to in the remainder of this discussion as the "sort work file". ORGANIZATION LINE SEQUENTIAL(see ORGANIZATION LINE SEQUENTIAL) orORGANIZATION SEQUENTIAL(see ORGANIZATION SEQUENTIAL) files. These files must be defined using a file description FD(see File/Sort-Description)). The same file(s) may be used for <file-name-1> and <file-name-2>. USINGclause (done automatically by the sort) or by utilizing an input procedure. USING INPUT PROCEDURE AGO TOstatement (see GO TO) that transfers control out of the input procedure will terminate theSORTstatement but allows the program to continue executing from the point where theGO TOstatement transferred control to. Once an input procedure has been "aborted" using aGO TOit cannot be resumed, and the contents of the sort work file are lost. You may, however, re-execute theSORTstatement itself. USING AGO TOstatement TO PREMATURELY TERMINATE A SORT, OR RE-STARTING A PREVIOUSLY-CANCELLED SORT IS NOT CONSIDERED GOOD PROGRAMMING STYLE AND SHOULD BE AVOIDED.
An input procedure should be terminated in the same way a proceduralPERFORMstatement would be.
Neither a another file-basedSORTstatement nor aMERGEstatement may be executed within the input procedure unless those statements utilize a different sort or merge work file.
KEYspecification(s) on theSORTstatement according to theCOLLATING SEQUENCEspecified on theSORT(if any) or — if none was defined — thePROGRAM COLLATING SEQUENCE(see OBJECT-COMPUTER). Keys may be any supported data type andUSAGE(see USAGE) except for level-78 or level-88 data items. SORT Sort-File
ASCENDING KEY Transaction-Date
ASCENDING KEY Account-Number
DESCENDING KEY Transaction-Amount
The effect of this statement will be to sort all transactions into ascending order of the date the transaction took place (oldest first, newest last). Unless the business running this program is going out of business, there are most-likely many transactions for any given date. Therefore, within each grouping of transactions all with the same date, transactions will be sub-sorted into ascending sequence of the account number the transactions apply to. Since it’s quite possible there might be multiple transactions for an account on any given date, a third level sub-sort will arrange all transactions for the same account on the same date into descending sequence of the actual amount of the transaction (largest first, smallest last). If two or more transactions of $100.00 were recorded for account #12345 on the 31st of August 2009, those transactions will be retained in the order in which they were loaded into the sort work file.
GIVING OUTPUT PROCEDURE AGO TOstatement (see GO TO) that transfers control out of the output procedure will terminate theSORTstatement but allows the program to continue executing from the point where theGO TOstatement transferred control to. Once an output procedure has been "aborted" using aGO TOit cannot be resumed, and the contents of the sort work file are lost. You may, however, re-execute theSORTstatement itself. USING AGO TOstatement TO PREMATURELY TERMINATE A SORT, OR RE-STARTING A PREVIOUSLY-CANCELLED SORT IS NOT CONSIDERED GOOD PROGRAMMING STYLE AND SHOULD BE AVOIDED.
An output procedure should be terminated in the same way a proceduralPERFORMstatement would be.
Neither a another file-basedSORTstatement nor aMERGEstatement may be executed within the output procedure unless those statements utilize a different sort or merge work file.
SORT table-name-1
~~~~
{ ON { ASCENDING } KEY identifier-1... }...
{ ~~~~~~~~~ }
{ DESCENDING }
~~~~~~~~~~
[ WITH DUPLICATES IN ORDER ]
~~~~~~~~~~
[ COLLATING SEQUENCE IS alphabet-name-1 ]
~~~~~~~~~ TheDUPLICATES
INISKEYONORDERSEQUENCEandWITHare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. WITH DUPLICATES IN ORDERclause is specified, even if it isn’t. While any COBOL implementation’s sort or merge facilities guarantee that records with duplicate key values will be in proper sequence with regard to other records with different key values, they generally make no promises as to the resulting relative sequence of records having duplicate key values with one another.
Some COBOL implementations provide this optional clause to force their sort and merge facilities to retain duplicate key-value records in their original input sequence, relative to one another.
KEYspecification(s) on theSORTstatement, according to theCOLLATING SEQUENCEspecified on theSORT(if any) or — if none was defined — thePROGRAM COLLATING SEQUENCE(see OBJECT-COMPUTER). Keys may be any supported data type andUSAGE(see USAGE) except for level-78 or level-88 data items. SEARCH ALLstatement (see SEARCH ALL), care must be taken that theKEYspecifications on theSORTagree with those in the table’s definition. KEYspecification(s) made on theSORTstatement is unsupported by GnuCOBOL and will be rejected by the compiler. START file-name-1
~~~~~
[ { FIRST } ]
{ ~~~~~ }
{ LAST }
{ ~~~~ }
{ KEY { IS EQUAL TO | IS = | EQUALS } identifier-1 }
{ ~~~~~ ~~~~~~ }
{ IS GREATER THAN | IS > }
{ ~~~~~~~ }
{ IS GREATER THAN OR EQUAL TO | IS >= }
{ ~~~~~~~ ~~ ~~~~~ }
{ IS NOT LESS THAN }
{ ~~~ ~~~~ }
{ IS LESS THAN | IS < }
{ ~~~~ }
{ IS LESS THAN OR EQUAL TO | IS <= }
{ ~~~~ ~~ ~~~~~ }
{ IS NOT GREATER THAN }
~~~ ~~~~~~~
[ INVALID KEY imperative-statement-1 ]
~~~~~~~
[ NOT INVALID KEY imperative-statement-2 ]
~~~ ~~~~~~~
[ END-START ]
~~~~~~~~~ ISKEYTHANandTOare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. ORGANIZATION RELATIVE(see ORGANIZATION RELATIVE) orORGANIZATION INDEXED(see ORGANIZATION INDEXED) file that must have been defined with anACCESS MODE DYNAMICorACCESS MODE SEQUENTIALin itsSELECTstatement (see SELECT). INPUTorI-O(see File OPEN Modes) mode. RELATIVE KEYof the file. RECORD KEYof the file or any of theALTERNATE RECORD KEYfields for the file. FIRSTLASTorKEYclause is specified,KEY IS EQUAL TO xxxwill be assumed, where "xxx" is the definedRELATIVE KEYof (if <file-name-1> is a relative file) or the definedRECORD KEY(if <file-name-1> is an indexed file). STARTstatement, the internal logical record pointer into the <file-name-1> data will be positioned to the record which satisfied the actual or impliedFIRSTLASTorKEYclause specification, as follows: FIRSTwas specified, the logical record pointer will point to the first record in the file. LASTwas specified, the logical record pointer will point to the last record in the file. KEYwas specified or implied, the logical record pointer will be specified to the first record satisfying the relation condition; to identify this record, the file’s contents are searched in a first-to-last (in sequence of the key implied by theKEYclause), provided the relation isEQUAL TOGREATER THANorGREATER THAN OR EQUAL TO(or any of their syntactical equivalents). KEYwas specified or implied, the logical record pointer will be specified to the last record satisfying the relation condition; to identify this record, the file’s contents are searched in a last-to-first (in sequence of the key implied by theKEYclause), provided the relation isLESS THANLESS THAN OR EQUAL TOorNOT GREATER THAN(or any of their syntactical equivalents). The next sequentialREADstatement will read the record that is pointed to by the logical record pointer.
INVALID KEYandNOT INVALID KEYclauses may be used to detect and react to the failure or success, respectively, by detecting non-zero (typically 23 = key not found = record not found) and 00 file status codes, respectively. See File Status Codes, for additional information. STOP { RUN [ { RETURNING|GIVING { literal-1 } } ] }
~~~~ { ~~~ { ~~~~~~~~~ ~~~~~~ { identifier-1 } } }
{ { } }
{ { WITH { ERROR } STATUS [ { literal-2 } ] } }
{ { { ~~~~~ } { identifier-2 } } }
{ { { NORMAL } } }
{ ~~~~~~ }
{ literal-3 } STATUSandWITHare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. RETURNING RUN SYSOUTSTDOUTdevice, waits for the user to press the Enter key and then — once the key has been pressed — allows the program to continue execution. RETURNINGclause provides the opportunity to return a numeric value to the operating system (a "return code"). The manner in which the return code may be interrogated by the operating system varies, but Windows can use%ERRORLEVEL%to query the return code while Unix shells such as sh, bash and ksh can query the return code as$? Other Unix shells may have different ways to access return code values. STATUS STATUSclause without a <literal-2> or <identifier-2> will return a return code of 0 if theNORMAL RETURNINGorSTATUSclause is specified. In the absence of the use of these clauses, the value in theRETURN-CODEspecial register (see Special Registers) at the time theSTOPstatement is executed will be used as the return code. CBL_EXIT_PROCbuilt-in system subroutine (see CBL_EXIT_PROC)) will be executed bySTOP RUN but not bySTOP <literal-3> STOP RUN RETURNING 16 MOVE 16 TO RETURN-CODE STOP RUN STOP RUN WITH ERROR STATUS 16
STRING
~~~~~~
{ { literal-1 } [ DELIMITED BY { SIZE } ] }...
{ identifier-1 } ~~~~~~~~~ { ~~~~ }
{ literal-2 }
INTO identifier-3 { identifier-2 }
~~~~
[ WITH POINTER identifier-4 ]
~~~~~~~
[ ON OVERFLOW imperative-statement-1 ]
~~~~~~~~
[ NOT ON OVERFLOW imperative-statement-2 ]
~~~ ~~~~~~~~
[ END-STRING ]
~~~~~~~~~~ BYONandWITHare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. USAGE(see USAGE) ofDISPLAY Any of the identifiers may be group items. POINTER STRINGstatement’s processing is based upon a ’current character pointer’ DELIMITED BY DELIMITED BY <literal-2>orDELIMITED BY <identifier-2>causes only the contents of the source item up to but not including the character sequence specified by the literal or identifier to be copied. STRINGprocessing will cease when one of the following occurs: STRINGstatement nor will it be space-filled should the total number of sending item characters copied into it be less than its size. You may explicitly initialize <identifier-3> yourself via theINITIALIZE(see INITIALIZE) orMOVE(see MOVE) statements before executing theSTRINGif you wish. ON OVERFLOWandNOT ON OVERFLOWclauses may be used to detect and react to the occurrence or not, respectively, of an overflow condition. See ON OVERFLOW + NOT ON OVERFLOW, for additional information. SUBTRACT { literal-1 }... FROM { identifier-2
~~~~~~~~ { identifier-1 } ~~~~
[ ROUNDED [ MODE IS { AWAY-FROM-ZERO } ] ] }...
~~~~~~~ ~~~~ { ~~~~~~~~~~~~~~ }
{ NEAREST-AWAY-FROM-ZERO }
{ ~~~~~~~~~~~~~~~~~~~~~~ }
{ NEAREST-EVEN }
{ ~~~~~~~~~~~~ }
{ NEAREST-TOWARD-ZERO }
{ ~~~~~~~~~~~~~~~~~~~ }
{ PROHIBITED }
{ ~~~~~~~~~~ }
{ TOWARD-GREATER }
{ ~~~~~~~~~~~~~~ }
{ TOWARD-LESSER }
{ ~~~~~~~~~~~~~ }
{ TRUNCATION }
~~~~~~~~~~
[ ON SIZE ERROR imperative-statement-1 ]
~~~~ ~~~~~
[ NOT ON SIZE ERROR imperative-statement-2 ]
~~~ ~~~~ ~~~~~
[ END-SUBTRACT ]
~~~~~~~~~~~~ ISandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. ROUNDED(see ROUNDED) clause available to each <identifier-2> will control how non-integer results will be saved. ON SIZE ERRORandNOT ON SIZE ERRORclauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-2> with an insufficient number of digit positions available to the left of any implied decimal point. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information. SUBTRACT { literal-1 }... FROM identifier-2
~~~~~~~~ { identifier-1 } ~~~~
GIVING { identifier-3
~~~~~~
[ ROUNDED [ MODE IS { AWAY-FROM-ZERO } ] ] }...
~~~~~~~ ~~~~ { ~~~~~~~~~~~~~~ }
{ NEAREST-AWAY-FROM-ZERO }
{ ~~~~~~~~~~~~~~~~~~~~~~ }
{ NEAREST-EVEN }
{ ~~~~~~~~~~~~ }
{ NEAREST-TOWARD-ZERO }
{ ~~~~~~~~~~~~~~~~~~~ }
{ PROHIBITED }
{ ~~~~~~~~~~ }
{ TOWARD-GREATER }
{ ~~~~~~~~~~~~~~ }
{ TOWARD-LESSER }
{ ~~~~~~~~~~~~~ }
{ TRUNCATION }
~~~~~~~~~~
[ ON SIZE ERROR imperative-statement-1 ]
~~~~ ~~~~~
[ NOT ON SIZE ERROR imperative-statement-2 ]
~~~ ~~~~ ~~~~~
[ END-SUBTRACT ]
~~~~~~~~~~~~ ISandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. ROUNDED(see ROUNDED) clause available to each <identifier-2> will control how non-integer results will be saved. ON SIZE ERRORandNOT ON SIZE ERRORclauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-2> with an insufficient number of digit positions available to the left of any implied decimal point. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information. SUBTRACT CORRESPONDING identifier-1 FROM identifier-2
~~~~~~~~ ~~~~
[ ROUNDED [ MODE IS { AWAY-FROM-ZERO } ] ]
~~~~~~~ ~~~~ { ~~~~~~~~~~~~~~ }
{ NEAREST-AWAY-FROM-ZERO }
{ ~~~~~~~~~~~~~~~~~~~~~~ }
{ NEAREST-EVEN }
{ ~~~~~~~~~~~~ }
{ NEAREST-TOWARD-ZERO }
{ ~~~~~~~~~~~~~~~~~~~ }
{ PROHIBITED }
{ ~~~~~~~~~~ }
{ TOWARD-GREATER }
{ ~~~~~~~~~~~~~~ }
{ TOWARD-LESSER }
{ ~~~~~~~~~~~~~ }
{ TRUNCATION }
~~~~~~~~~~
[ ON SIZE ERROR imperative-statement-1 ]
~~~~ ~~~~~
[ NOT ON SIZE ERROR imperative-statement-2 ]
~~~ ~~~~ ~~~~~
[ END-SUBTRACT ]
~~~~~~~~~~~~ ISandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. ROUNDED(see ROUNDED) clause available to each <identifier-2> will control how non-integer results will be saved. ON SIZE ERRORandNOT ON SIZE ERRORclauses may be used to detect and react to the failure or success, respectively, of an attempt to perform a calculation. In this case, failure is defined as being an <identifier-2> with an insufficient number of digit positions available to the left of any implied decimal point. See ON SIZE ERROR + NOT ON SIZE ERROR, for additional information. SUPPRESS PRINTING ~~~~~~~~
PRINTINGis optional and may be included, or not, at the discretion of the programmer. The presence or absence of this word has no effect upon the program. USE BEFORE REPORTINGprocedure (inDECLARATIVES(see DECLARATIVES)). SUPPRESSonly prevents the presentation of the report group within whoseUSE BEFORE REPORTINGprocedure the statement occurs. LINE(see LINE) clauses within the report group in question. NEXT GROUP(see NEXT GROUP) clause (if any) within the report group in question. LINE-COUNTERspecial register (see Special Registers). PAGE-COUNTERspecial register . TERMINATE report-name-1... ~~~~~~~~~
RD(see REPORT SECTION) defined for it. INITIATE(see INITIATE)) and cannot yet have been terminated. TERMINATEstatement will present eachCONTROL FOOTING(if any), in reverse sequence of the control hierarchy, starting with the most minor up toFINAL(if any). During the presentation of these groups and the processing of anyUSE BEFORE REPORTINGprocedures for those groups, the prior set of control data item values will be available, as though a control break had been detected at the most major control data name. CONTROL FOOTINGgroups, any necessaryPAGE FOOTINGandPAGE HEADINGgroups will be presented as well. REPORT FOOTINGgroup, if any, will be presented. INITIATEis followed by aTERMINATEwith no interveningGENERATE(see GENERATE) statements (all pertaining to the same report, of course), no report groups will be presented to the output file. TRANSFORM identifier-1 FROM { literal-1 } TO { literal-2 }
~~~~~~~~~ ~~~~ { identifier-2 } ~~ { identifier-3 } USAGE(see USAGE) ofDISPLAYare accepted, but will generate warning messages from the compiler. TRANSFORMstatement will replace characters within <identifier-1> that are found in the string specified before theTOkeyword with the corresponding characters from the string specified after theTOkeyword. TRANSFORMstatement was made obsolete in the 1985 standard of COBOL, having been replaced by theCONVERTINGclause of theINSPECTstatement (see INSPECT). New programs should be coded to useINSPECT CONVERTINGrather thanTRANSFORM UNLOCK filename-1 RECORD|RECORDS ~~~~~~
RECORDandRECORDSare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. UNSTRING identifier-1
~~~~~~~~
DELIMITED BY { [ ALL ] literal-1 } [ OR { [ ALL ] literal-2 } ]...
~~~~~~~~~ { ~~~ } ~~ { ~~~ }
{ identifier-2 } { identifier-3 }
INTO { identifier-4
~~~~ [ DELIMITER IN identifier-5 ] [ COUNT IN identifier-6 ] }...
~~~~~~~~~ ~~~~~
[ WITH POINTER identifier-7 ]
~~~~~~~
[ TALLYING IN identifier-8 ]
~~~~~~~~
[ ON OVERFLOW imperative-statement-1 ]
~~~~~~~~
[ NOT ON OVERFLOW imperative-statement-2 ]
~~~ ~~~~~~~~
[ END-UNSTRING ]
~~~~~~~~~~~~ BYINandONare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. USAGE(see USAGE) ofDISPLAY Any of those identifiers may be group items. UNSTRINGstatement begins execution, <identifier-7> must have a value greater than 0. UNSTRINGstatement’s processing is based upon a ’current character pointer’, the initial value of which will be the value of <identifier-7> at the time theUNSTRINGstatement began execution. If noPOINTERclause is coded, a value of 1 (meaning "the 1st character position") will be assumed for the current character pointer’s initial value. DELIMITED BY ALL JUSTIFIED(see JUSTIFIED) clause on the destination field. DELIMITER COUNT TALLYINGclause is coded, <identifier-8> will be incremented by 1 each time a destination field is populated. UNSTRINGstatement. You need to do that yourself via aMOVE(see MOVE) orINITIALIZEstatement (see INITIALIZE). UNSTRINGprocessing will cease when one of the following occurs: DELIMITERor <COUNT> identifiers) will be changed. ON OVERFLOWandNOT ON OVERFLOWclauses may be used to detect and react to the occurrence or not, respectively, of an overflow condition. See ON OVERFLOW + NOT ON OVERFLOW, for additional information. The following sample program illustrates theUNSTRINGstatement statement.
IDENTIFICATION DIVISION.
PROGRAM-ID. DEMOUNSTRING.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Full-Name PIC X(40).
01 Parsed-Info.
05 Last-Name PIC X(15).
05 First-Name PIC X(15).
05 MI PIC X(1).
05 Delim-LN PIC X(1).
05 Delim-FN PIC X(1).
05 Delim-MI PIC X(1).
05 Count-LN BINARY-CHAR.
05 Count-FN BINARY-CHAR.
05 Count-MI BINARY-CHAR.
05 Tallying-Ctr BINARY-CHAR.
PROCEDURE DIVISION.
P1. PERFORM UNTIL EXIT
DISPLAY "Enter Full Name (null quits):"
WITH NO ADVANCING
ACCEPT Full-Name
IF Full-Name = SPACES
EXIT PERFORM
END-IF
INITIALIZE Parsed-Info
UNSTRING Full-Name
DELIMITED BY ", "
OR ","
OR ALL SPACES
INTO Last-Name
DELIMITER IN Delim-LN
COUNT IN Count-LN
First-Name
DELIMITER IN Delim-FN
COUNT IN Count-FN
MI
DELIMITER IN Delim-MI
COUNT IN Count-MI
TALLYING Tallying-Ctr
DISPLAY "First-Name=" First-Name
" Delim='" Delim-FN
"' Count=" Count-FN
DISPLAY "MI =" MI " "
" Delim='" Delim-MI
"' Count=" Count-MI
DISPLAY "Last-Name =" Last-Name
" Delim='" Delim-LN
"' Count=" Count-LN
DISPLAY "Tally= " Tallying-Ctr
END-PERFORM
DISPLAY "Bye!"
STOP RUN .
The following is sample output from the program:
Enter Full Name (null quits):Cutler, Gary L First-Name=Gary Delim=' ' Count=+004 MI =L Delim=' ' Count=+001 Last-Name =Cutler Delim=',' Count=+006 Tally= +003 Enter Full Name (null quits):Snoddgrass,Throckmorton,P First-Name=Throckmorton Delim=',' Count=+012 MI =P Delim=' ' Count=+001 Last-Name =Snoddgrass Delim=',' Count=+010 Tally= +003 Enter Full Name (null quits):Munster Herman First-Name=Herman Delim=' ' Count=+006 MI = Delim=' ' Count=+000 Last-Name =Munster Delim=' ' Count=+007 Tally= +002 Enter Full Name (null quits): Bye!
WRITE record-name-1
~~~~~
[ FROM { literal-1 } ]
~~~~ { identifier-1 }
[ WITH [ NO ] LOCK ]
~~ ~~~~
[ { BEFORE } ADVANCING { { literal-2 } LINE|LINES } ]
{ ~~~~~~ } { { identifier-2 }
{ AFTER } { PAGE }
~~~~~ { ~~~~ }
{ mnemonic-name-1 }
[ AT END-OF-PAGE|EOP imperative-statement-1 ]
~~~~~~~~~~~ ~~~
[ NOT AT END-OF-PAGE|EOP imperative-statement-2 ]
~~~ ~~~~~~~~~~~ ~~~
[ INVALID KEY imperative-statement-3 ]
~~~~~~~
[ NOT INVALID KEY imperative-statement-4 ]
~~~ ~~~~~~~
[ END-WRITE ]
~~~~~~~~~ ADVANCINGATKEYLINELINESandWITHare optional and may be included, or not, at the discretion of the programmer. The presence or absence of these words has no effect upon the program. END-OF-PAGEandEOPare interchangeable. FD(see File/Sort-Description)) of a file that is currently open forOUTPUT(see File OPEN Modes),EXTENDorI-O FROM LOCKoptions may be used to manually control access to the just-written record by other programs while this program is running. See Record Locking, to review the various record locking behaviour. INVALID KEYandNOT INVALID KEYclauses may be used when writing to relative or indexed files to detect and react to the failure (non-zero file status code) or success (00 file status code), respectively, of the statement. See File Status Codes, for additional information. WRITEis used against anORGANIZATION LINE SEQUENTIAL(see ORGANIZATION LINE SEQUENTIAL) file, with or without theLINE ADVANCING(see LINE ADVANCING) option, an end-of-record delimiter character sequence will be written to the file to signify where one record ends and the next record begins. This delimiter sequence will be either of the following: ADVANCINGclause: ORGANIZATION LINE SEQUENTIALwill either be rejected outright by the compiler (relative or indexed files) or may introduce unwanted characters into the file ORGANIZATION SEQUENTIAL(see ORGANIZATION SEQUENTIAL)). ADVANCINGclause is specified on aWRITEto a line-advancing file,AFTER ADVANCING 1 LINEwill be assumed; on other than line-advancing files,BEFORE ADVANCING 1 LINEwill be assumed. BEFORE ADVANCING AFTER ADVANCING ADVANCING n LINESclause will introduce the specified number of line-terminator character sequences into the file either before the written record AFTER ADVANCING or after the written record BEFORE ADVANCING. LINAGE(see File/Sort-Description) clause is absent from the file’sFD ADVANCING PAGE FD ADVANCING PAGEclause will introduce the appropriate number of line-terminator character sequences into the file either before the written record AFTER ADVANCING or after the written record BEFORE ADVANCING so as to force the printer to automatically advance to a new sheet of paper when the file prints. No formfeed characters will be generated whenLINAGEis specified — instead, it is assumed that the printer to which the report will be printed will be loaded with special forms that conform to the specifications defined by theLINAGEclause. LINAGE-COUNTERspecial register (see Special Registers) and theEND-OF-PAGE AT END-OF-PAGEclause will be triggered, thus executing <imperative-statement-1> (see Imperative Statement), if theWRITEstatement introduces a data line or line-feed character into the file at a line position within the Page Footer area defined by theLINAGEclause. TheNOT AT END-OF-PAGEclause will be triggered (thus executing <imperative-statement-2>) if no end-of-page condition occurred during theWRITE Please see availability notes on this at 1.3.13. There are a number of terms that describe various aspects of the operation of the Report Writer Control System (RWCS). Understanding the meanings of these terms is vital to developing an understanding of the subject.
An event that is triggered when a control field on an RWCS-generated report changes value. It is these events that trigger the generation of control heading and control footing groups.
A field of data being presented within a detail group; as the various detail groups that comprise the report are presented, they are presumed to appear in sorted sequence of the control fields contained within them. As an example, a department-by-department sales report for a chain of stores would probably be sorted by store number and – within like store numbers – be further sorted by department number. The store number will undoubtedly serve as a control field for the report, allowing control heading groups to be presented before each sequence of detail groups for the same store and control footing groups to be presented after each such sequence.
A report group that appears immediately after one or more detail groups of an RWCS-generated report. Such are produced automatically as a result of a control break. This type of group typically serves as a summary of the detail group(s) that precede it, as might be the case on a sales report for a chain of stores, where the detail groups documenting sales for each department (one department per detail group) from the same store might be followed by a control footing that provides a summation of the department-by-department sales for that store.
A report group that appears immediately before one or more detail groups of an RWCS-generated report. Such are produced automatically as a result of a control break. This type of group typically serves as an introduction to the detail group(s) that follow, as might be the case on a sales report for a chain of stores, where the detail groups documenting sales for each department (one department per detail group) from the same store might be preceded by a control heading that states the full name and location of the store.
A report group that contains the detailed data being presented for the report.
A report group that appears at the bottom of every page of an RWCS-generated report. Information typically found within such a report group might be:
A report group that appears at the top of every page of an RWCS-generated report. Information typically found within such a report group might be:
A report group that occurs only once in an RWCS-generated report — as the very last presented report group of the report. These typically serve as a visual indication that the report is finished.
One or more consecutive lines on a report that serve a common informational purpose or function. For example, lines of text that are displayed at the top or bottom of every printed page of a report.
A report group that occurs only once in an RWCS-generated report — as the very first presented report group of the report. These typically serve as an introduction to the report.
Every report has the same basic structure, as shown here, even though not all reports will have all of the groups shown. In fact, it is a very unusual report indeed that actually has every one of these groups:
FINALCONTROL FOOTING | [1] | Presented throughout the report, as needed |
| [2] | Repeated, as needed |
These groups will be presented (printed) across however many formatted pages are necessary to hold them. No single report group will be allowed to cross page boundaries.
The management of paging, enforcement of the "groups cannot span pages" rule and almost every aspect of report generation are handled entirely by the Report Writer Control System.
Each page of a report is divided into as many as five (5) areas, as shown in the following diagram.
_______________________________| || Top-of-page Unusable Area |—# Lines:LINES AT TOP(LINAGE)|_______________________________|| |—Line #:HEADING(RD)| Heading Area ||_______________________________|—Line #:FIRST DETAIL(RD) - 1| |—Line #:FIRST DETAIL(RD)| || Body Area |—Line #:LAST CONTROL HEADING(RD)| |—Line #:LAST DETAIL(RD)|_______________________________|—Line #:FOOTING(RD)| |—Line #:FOOTING(RD) + 1| Footing Area ||_______________________________|| || Bottom-of-page Unusable Area |—# Lines:LINES AT BOTTOM(LINAGE)|_______________________________|
When describing a report via theRD(see REPORT SECTION) clause, the total number of usable lines are specified as thePAGE LIMITvalue; this value is the sum of the number of lines contained in the Heading, Body and Footing Areas.
The unusable areas of a page (if any) will appear above and below that usable area. You don’t specify the unusable area in theRD but rather using aLINAGE(see File/Sort-Description) clause in theFDof the file the report is "attached" to.
The various report groups will be presentable in the various areas of a page, as follows:
REPORT HEADINGHeading Area — An exception to this is the situation where the report heading report group contains theNEXT GROUP NEXT PAGE(see NEXT GROUP) option; in those cases, the report heading will be presented on a page by itself (anywhere on that page) at the beginning of the report.
PAGE HEADINGHeading Area
CONTROL HEADINGBody Area, but no line of a control heading is allowed past the line number specified byLAST CONTROL HEADING
DETAILBody Area, but no line of a detail report group is allowed past the line number specified byLAST DETAIL
CONTROL FOOTINGBody Area, but no line of a control footing report group is allowed past the line number specified byFOOTING
PAGE FOOTINGFooting Area
REPORT FOOTINGFooting Area — An exception to this is the situation where the report footing report group contains theNEXT PAGEoption in itsLINE(see LINE) clause; in those cases, the report footing will be presented on a page by itself at the end of the report.
A report created via aWRITEstatement (see WRITE) will contain carriage-control information. Most notably, ASCII form-feed characters (X’0C’) will be written to the report file to support the statement’sADVANCING PAGEoption. Whether the data for a report line created viaADVANCING PAGEoccurs before or after the form-feed character depends upon whether the programmer codedWRITE <record-name> BEFORE ADVANCING PAGEorWRITE <record-name> AFTER ADVANCING PAGE respectively.
The GnuCOBOL implementation of RWCS does not issue any carriage-control information to the report files it produces — instead, it relies upon the information coded in theRDfor the report (specifically thePAGE LIMITSand related options) and it’s internally-generated and managedLINE-COUNTERspecial register (see Special Registers) for the report to know when to issue any blank lines to the file to fill-out the end of a printed page.
Because this is the way the GnuCOBOL RWCS works, in order to design an RWCS-generated report you’ll need to know answers to the following questions:
Once you know the answer to questions 1-4, you may easily determine the answers to the remaining questions as follows:
123456789012345678901234). PAGE LIMITvalue for theRD The remainingPAGE LIMITvalues can be established as required by your report(s).
Using <identifier> rather than <integer> specifications in theRDwill give your program the ability — at run time — to accommodate multiple printers, fonts, font sizes and paper orientation. Just follow the above steps for each combination you wish your program to support.
Every report that employs control breaks has a natural hierarchy of those control breaks based upon the manner in which the data the report is being generated from is sorted. This concept is best understood using an example which assumes a COBOL program to process sales data collected from every computerized cash register across a chain of stores having multiple departments is being developed.
The application that collects data from the various cash registers at each store will generate data records that look like this to a COBOL program:
01 Sales-For-Register.
05 Sales-Date PIC 9(8).
05 Time-Collected PIC 9(6).
05 Register-Number PIC 9(7).
05 Store-Number PIC 9(3).
05 Department-Number PIC 9(3).
05 Total-Sales PIC 9(6)V99.
Your task is to develop a report that shows the sales total from each cash register and summarizes those sales by department within each store, by store and also generates a total sales figure for the day across all stores.
To accomplish this, you will use aSORTstatement (see SORT) to sort the file of cash register sales data into:
So, assuming a sort file has been defined and it’s record layout (essentially a mirror of the raw data file) is defined as follows:
01 Sorted-Sales-For-Register.
05 Sorted-Sales-Date PIC 9(8).
05 Sorted-Time-Collected PIC 9(6).
05 Sorted-Register-Number PIC 9(7).
05 Sorted-Store-Number PIC 9(3).
05 Sorted-Department-Number PIC 9(3).
05 Sorted-Total-Sales PIC 9(6)V99.
Then theSORTstatement to accomplish the desired sequencing would be:
SORT SORT-FILE
ASCENDING KEY Sorted-Store-Number
Sorted-Department-Number
Sorted-Register-Number
USING Input-file
OUTPUT PROCEDURE 100-Generate-Report
As a result of the sort, our program might expect to see data somewhat like this (date, time and sales totals are shown as "…"):
+-------------------- Register Number | +------------- Store Number | | +---------- Department Number | | | ...0535240001001... ...0589130001001... ...0625174001001... ...0122234001002... ...0732345001002... ...0003423001003... ...2038774001004... ...0112646002001... ...9963348002002... ...3245677002003... ...4456778002003... ...0002345002004...
Because of the sort, the most-frequently changing value of the three sort keys will be that of Sorted-Register-Number. This essentially defines the "detail" level of the report.
The next most-frequently changing value is that of Sorted-Department-Number, and the least-frequently changing value is that of Sorted-Store-Number. remember that the program should be generating totals each time one of these two values change, plus a grand total of sales at the end of the report. These three points are the ’Control Break’
When the report is defined, it’sRDwould contain aCONTROLS AREclause that lists the control breaks in least- to most-frequent sequence of changing. This would be coded as:
CONTROLS ARE FINAL, Sorted-Store-Number, Sorted-Department-Number
A FINAL control break only occurs once, at the very end of the report. TheCONTROL FOOTINGfor this break will be the one that produces the grand total of sales for all stores.
The next break listed on theCONTROLSclause will be the one that occurs next most-frequently (Sorted-Store-Number). This control break will be the one that produces the summation for each entire store, and will have its ownCONTROL FOOTING
The next (and last, in this case) break listed on the CONTROLS clause will be the one that occurs even more frequently (Sorted-Department-Number). TheCONTROL FOOTINGfor this control field will be the one that summarizes sales for each department within a store.
This sequence of control breaks from least- to most-frequent (in other words, in the order they occur on the CONTROLS ARE clause) is the ’control hierarchy’ of the report; control breaks that occur more frequently than others are said to be at a lower level in the control hierarchy.
Defining a control hierarchy (viaCONTROLS ARE that does not match the actual sequence in which data will be processed is a great way to guarantee a "broken" report. I’ll show you an example in a later section.
This section contains an example of the RWCS at work. The complete program, presented here, is a stripped-down version of a program I have used to generate a report for a class I teach on PC hardware. This report will provide benchmark statistics on a variety of popular AMD and Intel CPUs. The data for the report was obtained from the website www.cpubenchmark.net in December of 2013. By the time you are reading this, that data will most likely have become rather out-of-date, but it illustrates RWCS well enough.
Here is the data that the program will be reading. Each record reflects the aggregated benchmark scoring for one particular CPU, as scores for benchmarks against that CPU have been reported to the cpubenchmark.net website by their PassMark benchmark software. The data consists of four fields. Fields are separated from one another by a single comma. The descriptions of the fields are as follows:
A five-digit number showing the aggregated benchmark scores for the CPU; the higher this number, the better the CPU performed in benchmark testing.
The name of the vendor who makes the CPU. In this data, that will either be "AMD" (American Micro Devices) or "INTEL".
The 7-character family of CPU products the CPU falls into. This will have values such as "A4", "A10", "Core i5", "Core i7", etc.
The specific model of CPU within the family.
The first record of data shown below shows that the aggregated score of all benchmarks reported for the AMD A10-4600M CPU is 3145, as compared to the second record which shows that the aggregated score reported of all benchmarks reported for the Intel Core-i7-4960X CPU is 14291.
The following is the complete set of input data used for this example. This is by no means the complete set of data available at cpubenchmark.net – it is just a representative sample used for this example. For my class, I give my students a report showing the results for almost a thousand CPUs.
For the sake of brevity, this document lists the data in three columns.
03145,AMD,A10,4600M 05421,AMD,FX,6100 03917,Intel,Core i5,4300U 14291,Intel,Core i7,4960X 05813,AMD,FX,6120 01743,Intel,Core i5,4300Y 02505,AMD,A10,4655M 06194,AMD,FX,6200 04804,Intel,Core i5,4330M 03449,AMD,A10,4657M 06388,AMD,FX,6300 03604,Intel,Core i5,4350U 04251,AMD,A10,5700 07017,AMD,FX,6350 06282,Intel,Core i5,4430 02758,AMD,A10,5745M 06163,AMD,FX,8100 05954,Intel,Core i5,4430S 03332,AMD,A10,5750M 06605,AMD,FX,8120 06517,Intel,Core i5,4440 03253,AMD,A10,5757M 06845,AMD,FX,8140 07061,Intel,Core i5,4570 04798,AMD,A10,5800B 07719,AMD,FX,8150 06474,Intel,Core i5,4570R 04677,AMD,A10,5800K 08131,AMD,FX,8320 06803,Intel,Core i5,4570S 04767,AMD,A10,6700 09067,AMD,FX,8350 02503,Intel,Core i5,4570T 05062,AMD,A10,6800K 09807,AMD,FX,9370 07492,Intel,Core i5,4670 00677,AMD,A4,1200 10479,AMD,FX,9590 07565,Intel,Core i5,4670K 00559,AMD,A4,1250 03076,Intel,Core i3,3110M 06351,Intel,Core i5,4670T 01583,AMD,A4,3300 03301,Intel,Core i3,3120M 03701,Intel,Core i7,3517U 01237,AMD,A4,3300M 03655,Intel,Core i3,3130M 03449,Intel,Core i7,3517UE 01227,AMD,A4,3305M 03820,Intel,Core i3,3210 04588,Intel,Core i7,3520M 01263,AMD,A4,3310MX 02266,Intel,Core i3,3217U 03912,Intel,Core i7,3537U 01193,AMD,A4,3320M 04219,Intel,Core i3,3220 04861,Intel,Core i7,3540M 01343,AMD,A4,3330MX 03724,Intel,Core i3,3220T 04009,Intel,Core i7,3555LE 01625,AMD,A4,3400 04407,Intel,Core i3,3225 06144,Intel,Core i7,3610QE 01768,AMD,A4,3420 02575,Intel,Core i3,3227U 07532,Intel,Core i7,3610QM 01685,AMD,A4,4300M 01885,Intel,Core i3,3229Y 06988,Intel,Core i7,3612QE 01169,AMD,A4,4355M 04259,Intel,Core i3,3240 06907,Intel,Core i7,3612QM 01919,AMD,A4,5000 03793,Intel,Core i3,3240T 05495,Intel,Core i7,3615QE 01973,AMD,A4,5150M 04414,Intel,Core i3,3245 07310,Intel,Core i7,3615QM 02078,AMD,A4,5300 04757,Intel,Core i3,3250 07759,Intel,Core i7,3630QM 01632,AMD,A4,5300B 03443,Intel,Core i3,4000M 07055,Intel,Core i7,3632QM 02305,AMD,A4,6300 02459,Intel,Core i3,4010U 06516,Intel,Core i7,3635QM 01634,AMD,A6,1450 02003,Intel,Core i3,4010Y 04032,Intel,Core i7,3667U 01964,AMD,A6,3400M 04904,Intel,Core i3,4130 04271,Intel,Core i7,3687U 02101,AMD,A6,3410MX 04041,Intel,Core i3,4130T 03479,Intel,Core i7,3689Y 02078,AMD,A6,3420M 05115,Intel,Core i3,4330 08347,Intel,Core i7,3720QM 02277,AMD,A6,3430MX 05117,Intel,Core i3,4340 08512,Intel,Core i7,3740QM 01995,AMD,A6,3500 03807,Intel,Core i5,3210M 09420,Intel,Core i7,3770 02798,AMD,A6,3600 03995,Intel,Core i5,3230M 09578,Intel,Core i7,3770K 02892,AMD,A6,3620 03126,Intel,Core i5,3317U 09074,Intel,Core i7,3770S 03232,AMD,A6,3650 04101,Intel,Core i5,3320M 08280,Intel,Core i7,3770T 03327,AMD,A6,3670 05902,Intel,Core i5,3330 08995,Intel,Core i7,3820 01630,AMD,A6,4400M 05690,Intel,Core i5,3330S 08548,Intel,Core i7,3820QM 01296,AMD,A6,4455M 05781,Intel,Core i5,3335S 09025,Intel,Core i7,3840QM 02440,AMD,A6,5200 03280,Intel,Core i5,3337U 09196,Intel,Core i7,3920XM 01958,AMD,A6,5350M 02252,Intel,Core i5,3339Y 12107,Intel,Core i7,3930K 01878,AMD,A6,5357M 06282,Intel,Core i5,3340 09052,Intel,Core i7,3940XM 01906,AMD,A6,5400B 04327,Intel,Core i5,3340M 12718,Intel,Core i7,3960X 02174,AMD,A6,5400K 05372,Intel,Core i5,3340S 12823,Intel,Core i7,3970X 02384,AMD,A6,6400K 06199,Intel,Core i5,3350P 03992,Intel,Core i7,4500U 02050,AMD,A8,3500M 04314,Intel,Core i5,3360M 04507,Intel,Core i7,4558U 02426,AMD,A8,3510MX 04555,Intel,Core i5,3380M 04892,Intel,Core i7,4600M 02245,AMD,A8,3520M 03589,Intel,Core i5,3427U 04484,Intel,Core i7,4600U 02276,AMD,A8,3530MX 03479,Intel,Core i5,3437U 03680,Intel,Core i7,4610Y 02866,AMD,A8,3550MX 03057,Intel,Core i5,3439Y 04345,Intel,Core i7,4650U 03215,AMD,A8,3800 06442,Intel,Core i5,3450 07352,Intel,Core i7,4700EQ 03217,AMD,A8,3820 06071,Intel,Core i5,3450S 08161,Intel,Core i7,4700HQ 03552,AMD,A8,3850 06576,Intel,Core i5,3470 07946,Intel,Core i7,4700MQ 03682,AMD,A8,3870K 06077,Intel,Core i5,3470S 08002,Intel,Core i7,4702HQ 02709,AMD,A8,4500M 04591,Intel,Core i5,3470T 07647,Intel,Core i7,4702MQ 02193,AMD,A8,4555M 05991,Intel,Core i5,3475S 08066,Intel,Core i7,4750HQ 04052,AMD,A8,5500 06828,Intel,Core i5,3550 07367,Intel,Core i7,4765T 03464,AMD,A8,5500B 06631,Intel,Core i5,3550S 09969,Intel,Core i7,4770 02434,AMD,A8,5545M 06993,Intel,Core i5,3570 10190,Intel,Core i7,4770K 03052,AMD,A8,5550M 07118,Intel,Core i5,3570K 09803,Intel,Core i7,4770S 02935,AMD,A8,5557M 06709,Intel,Core i5,3570S 08803,Intel,Core i7,4770T 04348,AMD,A8,5600K 05414,Intel,Core i5,3570T 10078,Intel,Core i7,4771 04390,AMD,A8,6500 04333,Intel,Core i5,4200M 08567,Intel,Core i7,4800MQ 04719,AMD,A8,6600K 03355,Intel,Core i5,4200U 09969,Intel,Core i7,4820K 04055,AMD,FX,4100 02358,Intel,Core i5,4200Y 09331,Intel,Core i7,4850HQ 04153,AMD,FX,4130 02382,Intel,Core i5,4210Y 09323,Intel,Core i7,4900MQ 04094,AMD,FX,4150 03482,Intel,Core i5,4250U 13620,Intel,Core i7,4930K 04774,AMD,FX,4170 04381,Intel,Core i5,4258U 09754,Intel,Core i7,4930MX 04711,AMD,FX,4300 04663,Intel,Core i5,4288U 10262,Intel,Core i7,4960HQ 05247,AMD,FX,4350 04786,Intel,Core i5,4300M
Here is the program that will be producing the report. Pay attention to how the data is sorted and how the control hierarchy CONTROLS ARE relates to theSORT
IDENTIFICATION DIVISION.
PROGRAM-ID. DEMORWCS.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY. FUNCTION ALL INTRINSIC.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT CPU-FILE ASSIGN TO "CPUDATA.txt"
LINE SEQUENTIAL.
SELECT REPORT-FILE ASSIGN TO "CPUREPORT.txt"
LINE SEQUENTIAL.
SELECT SORT-FILE ASSIGN TO DISK.
DATA DIVISION.
FILE SECTION.
FD CPU-FILE.
01 CPU-REC PIC X(26).
FD REPORT-FILE
REPORT IS CPU-Report.
SD SORT-FILE.
01 SORT-REC.
05 F-SR-Score-NUM PIC 9(5).
05 F-SR-Vendor-TXT PIC X(5).
05 F-SR-Family-TXT PIC X(7).
05 F-SR-Model-TXT PIC X(6).
WORKING-STORAGE SECTION.
01 WS-Date PIC 9(8).
01 WS-Family-Counters.
05 WS-FC-AVE PIC 9(5)V99.
05 WS-FC-Qty BINARY-LONG.
05 WS-FC-Total-NUM BINARY-LONG.
01 WS-Flags.
05 WS-F-EOF PIC X(1).
01 WS-One-Const PIC 9 VALUE 1.
01 WS-Overall-Counters.
05 WS-OC-AVE PIC 9(5)V99.
05 WS-OC-Qty BINARY-LONG.
05 WS-OC-Total-NUM BINARY-LONG.
01 WS-Starz PIC X(44) VALUE ALL '*'.
01 WS-Vendor-Counters.
05 WS-VC-AVE PIC 9(5)V99.
05 WS-VC-Qty BINARY-LONG.
05 WS-VC-Total-NUM BINARY-LONG.
REPORT SECTION.
RD CPU-Report
CONTROLS ARE FINAL
F-SR-Vendor-TXT
F-SR-Family-TXT
PAGE LIMIT IS 36 LINES
HEADING 1
FIRST DETAIL 5
LAST DETAIL 36.
01 TYPE IS PAGE HEADING.
05 LINE NUMBER PLUS 1.
10 COL 1 SOURCE WS-Date PIC 9999/99/99.
10 COL 14 VALUE 'CPU Benchmark Scores'.
10 COL 37 VALUE 'Page:'.
10 COL 43 SOURCE PAGE-COUNTER PIC Z9.
05 LINE NUMBER PLUS 1.
10 COL 1 SOURCE WS-Starz PIC X(44).
05 LINE NUMBER PLUS 1.
10 COL 1 VALUE '**'.
10 COL 6 VALUE 'All CPU Data From cpubenchmark.net'.
10 COL 43 VALUE '**'.
05 LINE NUMBER PLUS 1.
10 COL 1 SOURCE WS-Starz PIC X(44).
01 TYPE CONTROL HEADING F-SR-Family-TXT.
05 LINE NUMBER PLUS 1.
10 COL 1 SOURCE F-SR-Vendor-TXT PIC X(6).
10 COL 8 SOURCE F-SR-Family-TXT PIC X(7).
05 LINE NUMBER PLUS 1.
10 COL 1 VALUE 'Family'.
10 COL 9 VALUE 'Model'.
10 COL 16 VALUE 'Benchmark Score (High to Low)'.
05 LINE NUMBER PLUS 1.
10 COL 1 VALUE '======'.
10 COL 9 VALUE '======'.
10 COL 16 VALUE '============================='.
01 Detail-Line TYPE IS DETAIL.
05 LINE NUMBER PLUS 1.
10 COL 1 SOURCE F-SR-Family-TXT PIC X(7) GROUP INDICATE.
10 COL 9 PIC X(6) SOURCE F-SR-Model-TXT.
10 COL 16 PIC ZZZZ9 SOURCE F-SR-Score-NUM.
01 End-Family TYPE IS CONTROL FOOTING F-SR-Family-TXT.
05 LINE NUMBER PLUS 1.
10 COL 9 VALUE 'Ave...'.
10 COL 16 PIC ZZZZ9.99 SOURCE WS-FC-AVE.
10 COL 25 VALUE '('.
10 COL 26 PIC ZZ9 SUM WS-One-Const.
10 COL 30 VALUE 'Family CPUs)'.
01 End-Vendor TYPE IS CONTROL FOOTING F-SR-Vendor-TXT.
05 LINE NUMBER PLUS 1.
10 COL 9 VALUE 'Ave...'.
10 COL 16 PIC ZZZZ9.99 SOURCE WS-VC-AVE.
10 COL 25 VALUE '('.
10 COL 26 PIC ZZ9 SUM WS-One-Const.
10 COL 30 VALUE 'Vendor CPUs)'.
01 End-Overall TYPE IS CONTROL FOOTING FINAL.
05 LINE NUMBER PLUS 1.
10 COL 9 VALUE 'Ave...'.
10 COL 16 PIC ZZZZ9.99 SOURCE WS-OC-AVE.
10 COL 25 VALUE '('.
10 COL 26 PIC ZZ9 SUM WS-One-Const.
10 COL 30 VALUE 'CPUs)'.
PROCEDURE DIVISION.
DECLARATIVES.
000-End-Family SECTION.
USE BEFORE REPORTING End-Family.
1. IF WS-FC-Qty > 0
COMPUTE WS-FC-AVE = WS-FC-Total-NUM / WS-FC-Qty
ELSE
MOVE 0 TO WS-FC-AVE
END-IF
MOVE 0 TO WS-FC-Qty
WS-FC-Total-NUM
.
000-End-Vendor SECTION.
USE BEFORE REPORTING End-Vendor.
1. IF WS-VC-Qty > 0
COMPUTE WS-VC-AVE = WS-VC-Total-NUM / WS-VC-Qty
ELSE
MOVE 0 TO WS-VC-AVE
END-IF
MOVE 0 TO WS-VC-Qty
WS-VC-Total-NUM
.
000-End-Overall SECTION.
USE BEFORE REPORTING End-Overall.
1. IF WS-OC-Qty > 0
COMPUTE WS-OC-AVE = WS-OC-Total-NUM / WS-OC-Qty
ELSE
MOVE 0 TO WS-OC-AVE
END-IF
MOVE 0 TO WS-OC-Qty
WS-OC-Total-NUM
.
END DECLARATIVES.
010-Main SECTION.
1. ACCEPT WS-Date FROM DATE YYYYMMDD
SORT SORT-FILE
ASCENDING KEY F-SR-Vendor-TXT
F-SR-Family-TXT
DESCENDING KEY F-SR-Score-NUM
ASCENDING KEY F-SR-Model-TXT
INPUT PROCEDURE 100-Pre-Process-Data
OUTPUT PROCEDURE 200-Generate-Report
STOP RUN
.
100-Pre-Process-Data SECTION.
1. OPEN INPUT CPU-FILE
PERFORM FOREVER
READ CPU-FILE
AT END
EXIT PERFORM
END-READ
MOVE SPACES TO SORT-REC
UNSTRING CPU-REC DELIMITED BY ','
INTO F-SR-Score-NUM,
F-SR-Vendor-TXT,
F-SR-Family-TXT,
F-SR-Model-TXT
RELEASE SORT-REC
END-PERFORM
CLOSE CPU-FILE
.
200-Generate-Report SECTION.
1. INITIALIZE WS-Family-Counters
WS-Flags
OPEN OUTPUT REPORT-FILE
INITIATE CPU-Report
RETURN SORT-FILE
AT END
MOVE 'Y' TO WS-F-EOF
END-RETURN
PERFORM UNTIL WS-F-EOF = 'Y'
GENERATE Detail-Line
ADD 1 TO WS-FC-Qty
WS-OC-Qty
WS-VC-Qty
ADD F-SR-Score-NUM TO WS-FC-Total-NUM
WS-OC-Total-NUM
WS-VC-Total-NUM
RETURN SORT-FILE
AT END
MOVE 'Y' TO WS-F-EOF
END-RETURN
END-PERFORM
TERMINATE CPU-Report
CLOSE REPORT-FILE
.
Finally, here’s the report the program generates!
2013/12/24 CPU Benchmark Scores Page: 1
********************************************
** All CPU Data From cpubenchmark.net **
********************************************
AMD A10
Family Model Benchmark Score (High to Low)
====== ====== =============================
A10 6800K 5062
5800B 4798
6700 4767
5800K 4677
5700 4251
4657M 3449
5750M 3332
5757M 3253
4600M 3145
5745M 2758
4655M 2505
Ave... 3817.90 ( 11 Family CPUs)
AMD A4
Family Model Benchmark Score (High to Low)
====== ====== =============================
A4 6300 2305
5300 2078
5150M 1973
5000 1919
3420 1768
4300M 1685
5300B 1632
3400 1625
3300 1583
3330MX 1343
3310MX 1263
3300M 1237
3305M 1227
3320M 1193
____________________________________________
2013/12/24 CPU Benchmark Scores Page: 2
********************************************
** All CPU Data From cpubenchmark.net **
********************************************
A4 4355M 1169
1200 677
1250 559
Ave... 1484.47 ( 17 Family CPUs)
AMD A6
Family Model Benchmark Score (High to Low)
====== ====== =============================
A6 3670 3327
3650 3232
3620 2892
3600 2798
5200 2440
6400K 2384
3430MX 2277
5400K 2174
3410MX 2101
3420M 2078
3500 1995
3400M 1964
5350M 1958
5400B 1906
5357M 1878
1450 1634
4400M 1630
4455M 1296
Ave... 2220.22 ( 18 Family CPUs)
AMD A8
Family Model Benchmark Score (High to Low)
====== ====== =============================
A8 6600K 4719
6500 4390
5600K 4348
____________________________________________
2013/12/24 CPU Benchmark Scores Page: 3
********************************************
** All CPU Data From cpubenchmark.net **
********************************************
A8 5500 4052
3870K 3682
3850 3552
5500B 3464
3820 3217
3800 3215
5550M 3052
5557M 2935
3550MX 2866
4500M 2709
5545M 2434
3510MX 2426
3530MX 2276
3520M 2245
4555M 2193
3500M 2050
Ave... 3148.68 ( 19 Family CPUs)
AMD FX
Family Model Benchmark Score (High to Low)
====== ====== =============================
FX 9590 10479
9370 9807
8350 9067
8320 8131
8150 7719
6350 7017
8140 6845
8120 6605
6300 6388
6200 6194
8100 6163
6120 5813
____________________________________________
2013/12/24 CPU Benchmark Scores Page: 4
********************************************
** All CPU Data From cpubenchmark.net **
********************************************
FX 6100 5421
4350 5247
4170 4774
4300 4711
4130 4153
4150 4094
4100 4055
Ave... 6457.00 ( 19 Family CPUs)
Ave... 3448.86 ( 84 Vendor CPUs)
Intel Core i3
Family Model Benchmark Score (High to Low)
====== ====== =============================
Core i3 4340 5117
4330 5115
4130 4904
3250 4757
3245 4414
3225 4407
3240 4259
3220 4219
4130T 4041
3210 3820
3240T 3793
3220T 3724
3130M 3655
4000M 3443
3120M 3301
3110M 3076
3227U 2575
4010U 2459
3217U 2266
4010Y 2003
____________________________________________
2013/12/24 CPU Benchmark Scores Page: 5
********************************************
** All CPU Data From cpubenchmark.net **
********************************************
Core i3 3229Y 1885
Ave... 3677.76 ( 21 Family CPUs)
Intel Core i5
Family Model Benchmark Score (High to Low)
====== ====== =============================
Core i5 4670K 7565
4670 7492
3570K 7118
4570 7061
3570 6993
3550 6828
4570S 6803
3570S 6709
3550S 6631
3470 6576
4440 6517
4570R 6474
3450 6442
4670T 6351
3340 6282
4430 6282
3350P 6199
3470S 6077
3450S 6071
3475S 5991
4430S 5954
3330 5902
3335S 5781
3330S 5690
3570T 5414
3340S 5372
4330M 4804
____________________________________________
2013/12/24 CPU Benchmark Scores Page: 6
********************************************
** All CPU Data From cpubenchmark.net **
********************************************
Core i5 4300M 4786
4288U 4663
3470T 4591
3380M 4555
4258U 4381
4200M 4333
3340M 4327
3360M 4314
3320M 4101
3230M 3995
4300U 3917
3210M 3807
4350U 3604
3427U 3589
4250U 3482
3437U 3479
4200U 3355
3337U 3280
3317U 3126
3439Y 3057
4570T 2503
4210Y 2382
4200Y 2358
3339Y 2252
4300Y 1743
Ave... 5026.13 ( 52 Family CPUs)
Intel Core i7
Family Model Benchmark Score (High to Low)
====== ====== =============================
Core i7 4960X 14291
4930K 13620
3970X 12823
____________________________________________
2013/12/24 CPU Benchmark Scores Page: 7
********************************************
** All CPU Data From cpubenchmark.net **
********************************************
Core i7 3960X 12718
3930K 12107
4960HQ 10262
4770K 10190
4771 10078
4770 9969
4820K 9969
4770S 9803
4930MX 9754
3770K 9578
3770 9420
4850HQ 9331
4900MQ 9323
3920XM 9196
3770S 9074
3940XM 9052
3840QM 9025
3820 8995
4770T 8803
4800MQ 8567
3820QM 8548
3740QM 8512
3720QM 8347
3770T 8280
4700HQ 8161
4750HQ 8066
4702HQ 8002
4700MQ 7946
3630QM 7759
4702MQ 7647
3610QM 7532
4765T 7367
____________________________________________
2013/12/24 CPU Benchmark Scores Page: 8
********************************************
** All CPU Data From cpubenchmark.net **
********************************************
Core i7 4700EQ 7352
3615QM 7310
3632QM 7055
3612QE 6988
3612QM 6907
3635QM 6516
3610QE 6144
3615QE 5495
4600M 4892
3540M 4861
3520M 4588
4558U 4507
4600U 4484
4650U 4345
3687U 4271
3667U 4032
3555LE 4009
4500U 3992
3537U 3912
3517U 3701
4610Y 3680
3689Y 3479
3517UE 3449
Ave... 7725.58 ( 58 Family CPUs)
Ave... 6005.16 (131 Vendor CPUs)
Ave... 5006.42 (215 CPUs)
____________________________________________
The sample program just discussed presents a great opportunity to show what can happen if you don’t define the control hierarchy of a report properly.
I changed theCONTROLS AREclause on the sample program from this:
CONTROLS ARE FINAL
F-SR-Vendor-TXT
F-SR-Family-TXT
To this:
CONTROLS ARE FINAL
F-SR-Family-TXT
F-SR-Vendor-TXT
And then ran the report again. Here are the first two pages of that new report. See what happened to the control breaks?
2013/12/24 CPU Benchmark Scores Page: 1
********************************************
** All CPU Data From cpubenchmark.net **
********************************************
AMD A10
Family Model Benchmark Score (High to Low)
====== ====== =============================
A10 6800K 5062
5800B 4798
6700 4767
5800K 4677
5700 4251
4657M 3449
5750M 3332
5757M 3253
4600M 3145
5745M 2758
4655M 2505
Ave... 3817.90 ( 11 Vendor CPUs)
Ave... 3817.90 ( 11 Family CPUs)
AMD A4
Family Model Benchmark Score (High to Low)
====== ====== =============================
A4 6300 2305
5300 2078
5150M 1973
5000 1919
3420 1768
4300M 1685
5300B 1632
3400 1625
3300 1583
3330MX 1343
3310MX 1263
3300M 1237
3305M 1227
____________________________________________
2013/12/24 CPU Benchmark Scores Page: 2
********************************************
** All CPU Data From cpubenchmark.net **
********************************************
A4 3320M 1193
4355M 1169
1200 677
1250 559
Ave... 1484.47 ( 17 Vendor CPUs)
Ave... 1484.47 ( 17 Family CPUs)
AMD A6
Family Model Benchmark Score (High to Low)
====== ====== =============================
A6 3670 3327
3650 3232
3620 2892
3600 2798
5200 2440
6400K 2384
3430MX 2277
5400K 2174
3410MX 2101
3420M 2078
3500 1995
3400M 1964
5350M 1958
5400B 1906
5357M 1878
1450 1634
4400M 1630
4455M 1296
Ave... 2220.22 ( 18 Vendor CPUs)
Ave... 2220.22 ( 18 Family CPUs)
AMD A8
Family Model Benchmark Score (High to Low)
====== ====== =============================
A8 6600K 4719
____________________________________________
You can trick RWCS into using the PAGE LIMIT values as logical specifications rather than physical ones quite easily — simply include an ASCII form-feed (X’0C’) character into your page heading design! Here’s how the sample program shown earlier could be easily modified:
Simply Change This…
01 TYPE IS PAGE HEADING.
05 LINE NUMBER 1.
10 COL 1 SOURCE WS-Date PIC 9999/99/99.
10 COL 14 VALUE 'CPU Benchmark Scores'.
10 COL 37 VALUE 'Page:'.
10 COL 43 SOURCE PAGE-COUNTER PIC Z9.
05 LINE NUMBER PLUS 1.
10 COL 1 SOURCE WS-Starz PIC X(44).
05 LINE NUMBER PLUS 1.
10 COL 1 VALUE '**'.
10 COL 6 VALUE 'All CPU Data From ' &
'cpubenchmark.net'.
10 COL 43 VALUE '**'.
05 LINE NUMBER PLUS 1.
10 COL 1 SOURCE WS-Starz PIC X(44).
To This…
01 TYPE IS PAGE HEADING.
05 LINE NUMBER 1. *> NEW
10 COL 1 VALUE X’0C’. *> NEW
05 LINE NUMBER PLUS 1. *> CHANGED
10 COL 1 SOURCE WS-Date PIC 9999/99/99.
10 COL 14 VALUE 'CPU Benchmark Scores'.
10 COL 37 VALUE 'Page:'.
10 COL 43 SOURCE PAGE-COUNTER PIC Z9.
05 LINE NUMBER PLUS 1.
10 COL 1 SOURCE WS-Starz PIC X(44).
05 LINE NUMBER PLUS 1.
10 COL 1 VALUE '**'.
10 COL 6 VALUE 'All CPU Data From ' &
'cpubenchmark.net'.
10 COL 43 VALUE '**'.
05 LINE NUMBER PLUS 1.
10 COL 1 SOURCE WS-Starz PIC X(44).
RWCS will still be counting lines to decide when to close off one page and start a new one, but when a new page is started it’s page heading will physically form-feed the printer when the report is printed. As long as any printer you plan on using supports at least as many physical print lines as what is defined as thePAGE LIMITvalue in whatever paper orientation and font you plan on (or are limited to) printing in, you have now divorced your program from the physical realities of the printer!
Of course, whatever software you are using to deliver the printed document to the printer with must allow the ASCII form-feed character to pass through to the printer.
Program source files should have extensions of ".cob" or ".cbl".
Program file names should match exactly the specification of PROGRAM-ID (including case).
Spaces cannot be included in primary entry-point names and therefore should not be included in program file names.
The GnuCOBOL compiler will translate your COBOL program into C source code, compile that C source code into executable binary form using the "C" compiler specified when GnuCOBOL was built and link that executable binary into:
This is an executable file directly-executable from the command-line. On Windows computers, this would be an ".exe" file. On Unix systems, this will be a file with no specific extension, but with execute permissions. This file will include the main program as well as any static-linked subprograms.
This is a single subprogram compiled into object-code form, ready to be linked in with a main program to form a directly-executable program. On windows computers, these generally are ".o" (object-code) files.
These are dynamically-loadable object code files ready to be invoked from other programs at execution time. On Windows systems, these would be ".dll" files, while on Unix systems they are typically ".so" files (OSX uses ".dylib").
The GnuCOBOL compiler is named "cobc" ("cobc.exe" on a Windows system).
The following describes the syntax and option switches of the cobc command. This information may be displayed by entering the command "cobc –help" or "cobc -h".
Usage: cobc [options]... file...
Options:
-h, -help display this help and exit
-V, -version display compiler version and exit
-i, -info display compiler information (build/environment)
-v, -verbose display compiler version and the commands
invoked by the compiler
-vv, -verbose=2 like -v but additional pass verbose option
to assembler/compiler
-vvv, -verbose=3 like -vv but additional pass verbose option
to linker
-q, -brief reduced displays, commands invoked not shown
-### like -v but commands not executed
-x build an executable program
-m build a dynamically loadable module (default)
-j [<args>], -job[=<args>]
run program after build, passing <args>
-std=<dialect> warnings/features for a specific dialect
<dialect> can be one of:
cobol2014, cobol2002, cobol85, default,
ibm, mvs, bs2000, mf, acu;
see configuration files in directory config
-F, -free use free source format
-fixed use fixed source format (default)
-O, -O2, -Os enable optimization
-g enable C compiler debug / stack check / trace
-d, -debug enable all run-time error checking
-o <file> place the output into <file>
-b combine all input files into a single
dynamically loadable module
-E preprocess only; do not compile or link
-C translation only; convert COBOL to C
-S compile only; output assembly file
-c compile and assemble, but do not link
-T <file> generate and place wide program listing into <file>
-t <file> generate and place a program listing into <file>
--tlines=<lines> specify lines per page in listing, default = 55
--tsymbols specify symbols in listing
-P[=<dir or file>] generate preprocessed program listing (.lst)
-Xref specify cross reference in listing
-I <directory> add <directory> to copy/include search path
-L <directory> add <directory> to library search path
-l <lib> link the library <lib>
-A <options> add <options> to the C compile phase
-Q <options> add <options> to the C link phase
-D <define> define <define> for COBOL compilation
-K <entry> generate CALL to <entry> as static
-conf=<file> user-defined dialect configuration; see -std
-list-reserved display reserved words
-list-intrinsics display intrinsic functions
-list-mnemonics display mnemonic names
-list-system display system routines
-save-temps[=<dir>] save intermediate files
- default: current directory
-ext <extension> add file extension for resolving COPY
-W enable all warnings
-Wall enable most warnings (all except as noted below)
-Wno-<warning> disable warning enabled by -W or -Wall
-Wno-unfinished do not warn if unfinished features are used
- ALWAYS active
-Wno-pending do not warn if pending features are mentioned
- ALWAYS active
-Wobsolete warn if obsolete features are used
-Warchaic warn if archaic features are used
-Wredefinition warn incompatible redefinition of data items
-Wconstant warn inconsistent constant
-Woverlap warn overlapping MOVE items
-Wpossible-overlap warn MOVE items that may overlap depending on
variables
- NOT set with -Wall
-Wparentheses warn lack of parentheses around AND within OR
-Wstrict-typing warn type mismatch strictly
-Wimplicit-define warn implicitly defined data items
-Wcorresponding warn CORRESPONDING with no matching items
-Winitial-value warn Initial VALUE clause ignored
-Wprototypes warn missing FUNCTION prototypes/definitions
-Warithmetic-osvs warn if arithmetic expression precision has changed
-Wcall-params warn non 01/77 items for CALL params
- NOT set with -Wall
-Wconstant-expression warn expressions that always resolve to true/false
-Wcolumn-overflow warn text after program-text area, FIXED format
- NOT set with -Wall
-Wterminator warn lack of scope terminator END-XXX
- NOT set with -Wall
-Wtruncate warn possible field truncation
- NOT set with -Wall
-Wlinkage warn dangling LINKAGE items
- NOT set with -Wall
-Wunreachable warn unreachable statements
- NOT set with -Wall
-Werror treat all warnings as errors
-Werror=<warning> treat specified <warning> as error
-fsign=[ASCII|EBCDIC] define display sign representation
- default: machine native
-ffold-copy=[UPPER|LOWER]
fold COPY subject to value
- default: no transformation
-ffold-call=[UPPER|LOWER]
fold PROGRAM-ID, CALL, CANCEL subject to value
- default: no transformation
-fdefaultbyte=0..255 or any quoted character
initialize fields without VALUE to decimal value
- default: initialize to picture
-fmax-errors=<number> maximum number of errors to report
- default: 100
-fintrinsics=[ALL|intrinsic function name(,name,...)]
intrinsics to be used without FUNCTION keyword
-ftrace generate trace code
- executed SECTION/PARAGRAPH
-ftraceall generate trace code
- executed SECTION/PARAGRAPH/STATEMENTS
- turned on by -debug
-fsyntax-only syntax error checking only; don't emit any output
-fdebugging-line enable debugging lines
- 'D' in indicator column or floating >>D
-fsource-location generate source location code
- turned on by -debug/-g/-ftraceall
-fimplicit-init automatic initialization of the COBOL runtime system
-fstack-check PERFORM stack checking
- turned on by -debug or -g
-fsyntax-extension allow syntax extensions
- e.g. switch name SW1, etc.
-fwrite-after use AFTER 1 for WRITE of LINE SEQUENTIAL
- default: BEFORE 1
-fmfcomment '*' or '/' in column 1 treated as comment
- FIXED format only
-facucomment '$' in indicator area treated as '*',
'|' treated as floating comment
-fnotrunc allow numeric field overflow
- non-ANSI behaviour
-fodoslide adjust items following OCCURS DEPENDING
- requires implicit/explicit relaxed syntax
-fsingle-quote use a single quote (apostrophe) for QUOTE
- default: double quote
-frecursive-check check recursive program call
-foptional-file treat all files as OPTIONAL
- unless NOT OPTIONAL specified
-ftab-width=1..12 set number of spaces that are asumed for tabs
-ftext-column=72..255 set right margin for source (fixed format only)
-fpic-length=<number> maximum number of characters allowed in the
character-string
-fword-length=1..61 maximum word-length for COBOL words / Programmer
defined words
-fliteral-length=<number>
maximum literal size in general
-fnumeric-literal-length=1..38
maximum numeric literal size
-fassign-clause=<value>
set way of interpreting ASSIGN
-fbinary-size=<value> binary byte size - defines the allocated bytes
according to PIC
-fbinary-byteorder=<value>
binary byte order
-ffilename-mapping resolve file names at run time using environment
variables.
-fpretty-display alternate formatting of numeric fields
-fbinary-truncate numeric truncation according to ANSI
-fcomplex-odo allow complex OCCURS DEPENDING ON
-findirect-redefines allow REDEFINES to other than last equal level number
-flarger-redefines-ok allow larger REDEFINES items
-frelax-syntax-checks allow certain syntax variations (e.g. REDEFINES
position)
-fperform-osvs exit point of any currently executing perform is
recognized if reached
-farithmetic-osvs limit precision in intermediate results to precision
of final result
-fmove-ibm MOVE operates as on IBM (left to right, byte by byte)
-fsticky-linkage LINKAGE-SECTION items remain allocated between
invocations
-frelax-level-hierarchy
allow non-matching level numbers
-fhostsign allow hexadecimal value 'F' for NUMERIC test of signed
PACKED DECIMAL field
-faccept-update set WITH UPDATE clause as default for ACCEPT dest-item,
instead of WITH NO UPDATE
-faccept-auto set WITH AUTO clause as default for ACCEPT dest-item,
instead of WITH TAB
-fconsole-is-crt assume CONSOLE IS CRT if not set otherwise
-fprogram-name-redefinition
program names don't lead to a reserved identifier
-fno-echo-means-secure
NO-ECHO hides input with asterisks like SECURE
-fcomment-paragraphs=<support>
comment paragraphs in IDENTIFICATION DIVISION (AUTHOR,
DATE-WRITTEN, ...)
-fmemory-size-clause=<support>
MEMORY-SIZE clause
-fmultiple-file-tape-clause=<support>
MULTIPLE-FILE-TAPE clause
-flabel-records-clause=<support>
LABEL-RECORDS clause
-fvalue-of-clause=<support>
VALUE-OF clause
-fdata-records-clause=<support>
DATA-RECORDS clause
-ftop-level-occurs-clause=<support>
OCCURS clause on top-level
-fsynchronized-clause=<support>
SYNCHRONIZED clause
-fgoto-statement-without-name=<support>
GOTO statement without name
-fstop-literal-statement=<support>
STOP-literal statement
-fstop-identifier-statement=<support>
STOP-identifier statement
-fdebugging-line=<support>
DEBUGGING MODE and indicator 'D'
-fuse-for-debugging=<support>
USE FOR DEBUGGING
-fpadding-character-clause=<support>
PADDING CHARACTER clause
-fnext-sentence-phrase=<support>
NEXT SENTENCE phrase
-flisting-statements=<support>
listing-directive statements EJECT, SKIP1, SKIP2,
SKIP3
-ftitle-statement=<support>
listing-directive statement TITLE
-fentry-statement=<support>
ENTRY statement
-fmove-noninteger-to-alphanumeric=<support>
move noninteger to alphanumeric
-fodo-without-to=<support>
OCCURS DEPENDING ON without to
-fsection-segments=<support>
section segments
-falter-statement=<support>
ALTER statement
-fcall-overflow=<support>
OVERFLOW clause for CALL
-fnumeric-boolean=<support>
boolean literals (B'1010')
-fhexadecimal-boolean=<support>
hexadecimal-boolean literals (BX'A')
-fnational-literals=<support>
national literals (N'UTF-16 string')
-fhexadecimal-national-literals=<support>
hexadecimal-national literals (NX'265E')
-facucobol-literals=<support>
ACUCOBOL-GT literals (#B #O #H #X)
-fword-continuation=<support>
continuation of COBOL words
-fnot-exception-before-exception=<support>
NOT ON EXCEPTION before ON EXCEPTION
-faccept-display-extensions=<support>
extensions to ACCEPT and DISPLAY
-frenames-uncommon-levels=<support>
RENAMES of 01-, 66- and 77-level items
-fconstant-78=<support>
constant with level 78 item (note: has left to right
precedence in expressions)
-fconstant-01=<support>
constant with level 01 CONSTANT AS/FROM item
-fprogram-prototypes=<support>
CALL/CANCEL with program-prototype-name
-freference-out-of-declaratives=<support>
references to sections not in DECLARATIVES from within
DECLARATIVES
-fnumeric-value-for-edited-item=<support>
numeric literals in VALUE clause of numeric-edited
items
-fincorrect-conf-sec-order=<support>
incorrect order of CONFIGURATOIN SECTION paragraphs
-fdefine-constant-directive=<support>
allow >> DEFINE CONSTANT var AS literal
where <support> is one of the following:
'ok', 'warning', 'archaic', 'obsolete', 'skip',
'ignore', 'error', 'unconformable'
-fnot-reserved=<word> word to be taken out of the reserved words list
-freserved=<word> word to be added to reserved words list
-freserved=<word>:<alias>
word to be added to reserved words list as alias
Each file specified on thecobccommand constitutes a ’Compilation Unit’
A compilation unit may also be a C-language source program, recognized as such by having a file extension of.cor an assembly-language program, recognized by its file extension of ".s". In such a case, COBOL compilation of that file will be bypassed by thecobccommand; instead, the file will be passed directly to the C compiler or assembler (executed automatically bycobc.
A compilation unit may also be an object-code module (output from the C compiler), recognized as such by having a file extension of.o In these situations, all compilation will be bypassed, and the object code will be "bound" into the generated executable by the loader (an "ld" command executed internally by thecobccommand).
Pre-compiled object-code subprograms may be automatically located by the GnuCOBOL compiler and the loader by using theLD_LIBRARY_PATHcompilation-time environment variable The collection of compilation units supplied on a singlecobcexecution constitute a ’Compilation Group’
The simplest mode of compilation is to generate a single executable file from one or more GnuCOBOL source files:
cobc -x mainprog.cbl sub1.cbl sub2.cblThe main program must be the first program found in the first compilation unit ("mainprog.cbl"). The remainder of that compilation unit as well as the rest of the files in the compilation group ("sub1.cbl" and "sub2.cbl") must be independent and/or contained subprograms (see Independent vs Contained vs Nested Subprograms).
This command assumes that all source files are in the directory from which thecobccommand was executed. You are, of course, free to include full pathnames with any filename, if necessary.
With the-xswitch
Any subroutines or user-defined functions that weren’t included in any of the source files comprising the compilation group will be treated as dynamically loadable subprograms (see Dynamic vs Static Subprograms).
Optionally, the-oswitch
Compilations may be performed to generate dynamically-loadable modules (or dynamically-loadable libraries, as they are frequently called). These compilations are performed by using the-mswitch
cobc -m mainprog.cbl sub1.cbl sub2.cblWhen the-mswitch is used, an operating-system specific dynamically-loadable module is generated for each individual compilation unit, using the filename of each compilation unit as the it’s module filename and either an extension of ".so" (UNIX, Windows/Cygwin), "dylib" (OSX) or ".dll" (Windows, Windows/MinGW).
You may compile GnuCOBOL subprograms into assembler source code which can then be assembled and linked with a main program when that main program is compiled. To create such an assembler source file, compile the subprogram(s) as follows:
cobc -S sprog1.cblThe above generates an assembler source file named "sprog1.s". If you have multiple subprograms to compile this way, just string their file names out on the command — each will be translated to it’s own assembler source file.
Later, when you wish to compile a calling program and combine any needed assembly language subroutines in (as static subroutines — see Dynamic vs Static Subprograms), use a command such as this:
cobc -x mainprog.cbl sprog1.sThe following are the various environment variables that can play a role in the compilation of GnuCOBOL programs.
COB_CC Set to the name of the C compiler you wish GnuCOBOL to use.
USE THIS FEATURE AT YOUR OWN RISK – YOU SHOULD ALWAYS USE THE C COMPILER YOUR GnuCOBOL BUILD WAS GENERATED FOR
COB_CFLAGS Set to any switches that you’d like to pass on to the C compiler from thecobccompiler (in addition to any thatcobcwill specify).
COB_CONFIG_DIR Set to the path to the folder where GnuCOBOL "config" files are kept.
COB_COPY_DIR If copybooks your program needs are NOT stored in the same directory as your program, set this environment variable to the folder in which the copybooks may be found (IBM mainframe programmers will recognize this as "SYSLIB").
COB_LDADD Set to any additional linker switches (ld) that can specify where standard libraries that must be linked with the program can be found. The default is "" (null).
COB_LDFLAGS Set to any linker/loader (ld) switches that you’d like to pass on to the C compiler from thecobccompiler (in addition to any that cobc will specify).
COB_LIBS Set to any linker switches (ld) that specify where standard libraries that must be linked with the program can be found.
COBCPY This environment variable provides an additional means of specifying where copybooks may be found by the compiler (see also COB_COPY_DIR, above).
LD_LIBRARY_PATH If you are planning on using static-linked subroutine libraries, set this variable to the path of the directory containing your libraries.
TMPDIR TMP Set to a directory/folder appropriate to create temporary files in. The intermediate working files created by the compiler will be created here (and deleted once they’re no longer needed).
The variableTMPDIRis checked for a valid path first; if that isn’t set, thenTMPis checked.
On a Windows system, theTMPenvironment variable is normally set for you when you logon. If you wish to use a different temporary folder, you may setTMPDIRyourself and have no fear of disrupting other Windows software that relies on TMP.
| * | These environment variables have default values established for them when the version of GnuCOBOL you are using was built. To see these default values, as well as other build-specific information, execute the command: cobc -i |
GnuCOBOL defines compilation variables when certain conditions are true.
If the condition associated with a variable is false, the variable is not defined during compilations.
Name Condition
DEBUG The -d debug flag is specified.
EXECUTABLE The module being compiled contains the main program.
GCCOMP The size of a COMP item is determined according to the GnuCOBOL
scheme, where for a PICTURE of length:
1-2, the item has 1 byte
3-4, the item has 2 bytes
5-9, the item has 4 bytes
10-18, the item has 8 bytes.
GNUCOBOL GnuCOBOL is compiling the source unit.
HOSTSIGNS A signed packed-decimal itemâs value may be considered NUMERIC
if the sign has value X"F".
IBMCOMP The size of a COMP item is determined according to the IBM
scheme, where for a PICTURE of length:
1-4, the item has 2 bytes
5-9, the item has 4 bytes
10-18, the item has 8 bytes.
MODULE The module being compiled does not contain the main program.
NOHOSTSIGNS A signed packed-decimal itemâs value may not be considered
NUMERIC if the sign has value X"F".
NOIBMCOMP The size of a COMP item is not determined according to the IBM
scheme.
NOSTICKYLINKAGE Sticky-linkage (linkage-section items remaining allocated
between invocations) is not enabled.
NOTRUNC Numeric data items are truncated according to their internal
representation.
P64 Pointers are greater than 32 bits long
STICKY-LINKAGE Sticky-linkage (linkage-section items remaining allocated
between invocations) is enabled.
TRUNC Numeric data items are truncated according to their PICTURE
clauses.
The GnuCOBOL compiler will attempt to locate copybooks by searching for them in the following folders. The search will occur in the sequence shown below, and will terminate once a copybook is found.
COPYstatement (see COPY). -Iswitch COBCPYcompilation-time environment variable A single folder may be named or multiple folders may be specified, separated by a system-appropriate delimiter character. When multiple folders are specified, they will be searched in the order they are named on the environment variable.
If the GnuCOBOL compiler you are using was built to utilize a native Windows environment, use a semicolon (;) as the delimiter character.
If, however, the GnuCOBOL compiler was built for a Unix, OSX or Linux environment, or was built for a Windows environment utilizing either the Cygwin or MinGW Unix emulators, use a colon character (:) as the delimiter.
As each of the above folders is searched for a copybook —COPY XXXXXXXX. for example — the GnuCOBOL compiler will attempt to locate the copybook file by any of the following names, in the sequence shown:
TheCOPYstatement is case-sensitive on UNIX systems;COPY copybooknameandCOPY COPYBOOKNAMEwill both fail to locate theCopyBookNamecopybook on a UNIX system.
Windows implementations of GnuCOBOL may, or may not, be similarly case sensitive with regard to copybook names, depending upon the Windows version and GnuCOBOL build options — it is safest to simply treat the COPY command as case-sensitive in all environments.
It is possible, however, to automatically cause allCOPYstatements to ’fold’ the names of all copybooks to upper-case by specifying the-ffold-copyswitch
Case-folding may also be turned on and off within the program source code using the CDF>>SETstatement (see >>SET).
GnuCOBOL uses compiler configuration files to define various options that will control the compilation process. These configuration files are specified using the-confswitch
If this is not defined under *nix it will default to /usr/local/share/gnucobol/config.
The following is a verbatim listing of the "default" configuration file (the one used if you don’t specify the-confswitch), just to show you the types of settings that may appear:
# GnuCOBOL compiler configuration # # Copyright (C) 2001-2012, 2014-2017 Free Software Foundation, Inc. # Written by Keisuke Nishida, Roger While, Simon Sobisch, Edward Hart # # Value: any string name: "GnuCOBOL" # Value: enum standard-define 0 # CB_STD_OC = 0, # CB_STD_MF, # CB_STD_IBM, # CB_STD_MVS, # CB_STD_BS2000, # CB_STD_ACU, # CB_STD_85, # CB_STD_2002, # CB_STD_2014 # Value: int tab-width: 8 text-column: 72 # Maximum word-length for COBOL words / Programmer defined words # Be aware that GC checks the word length against COB_MAX_WORDLEN # first (currently 61) word-length: 61 # Maximum literal size in general literal-length: 8191 # Maximum numeric literal size (absolute maximum: 38) numeric-literal-length: 38 # Maximum number of characters allowed in the character-string (max. 255) pic-length: 255 # Value: 'mf', 'ibm' # assign-clause: mf # If yes, file names are resolved at run time using # environment variables. # For example, given ASSIGN TO "DATAFILE", the file name will be # 1. the value of environment variable 'DD_DATAFILE' or # 2. the value of environment variable 'dd_DATAFILE' or # 3. the value of environment variable 'DATAFILE' or # 4. the literal "DATAFILE" # If no, the value of the assign clause is the file name. # filename-mapping: yes # Alternate formatting of numeric fields pretty-display: yes # Allow complex OCCURS DEPENDING ON complex-odo: no # Allow REDEFINES to other than last equal level number indirect-redefines: no # Binary byte size - defines the allocated bytes according to PIC # Value: signed unsigned bytes # ------ -------- ----- # '2-4-8' 1 - 4 same 2 # 5 - 9 same 4 # 10 - 18 same 8 # # '1-2-4-8' 1 - 2 same 1 # 3 - 4 same 2 # 5 - 9 same 4 # 10 - 18 same 8 # # '1--8' 1 - 2 1 - 2 1 # 3 - 4 3 - 4 2 # 5 - 6 5 - 7 3 # 7 - 9 8 - 9 4 # 10 - 11 10 - 12 5 # 12 - 14 13 - 14 6 # 15 - 16 15 - 16 7 # 17 - 18 17 - 18 8 # binary-size: 1-2-4-8 # Numeric truncation according to ANSI binary-truncate: yes # Binary byte order # Value: 'native', 'big-endian' binary-byteorder: big-endian # Allow larger REDEFINES items larger-redefines-ok: no # Allow certain syntax variations (eg. REDEFINES position) relax-syntax-checks: no # Perform type OSVS - If yes, the exit point of any currently # executing perform is recognized if reached. perform-osvs: no # Compute intermediate decimal results like IBM OSVS arithmetic-osvs: no # MOVE like IBM (mvc); left to right, byte by byte move-ibm: no # If yes, linkage-section items remain allocated # between invocations. sticky-linkage: no # If yes, allow non-matching level numbers relax-level-hierarchy: no # If yes, evaluate constant expressions at compile time constant-folding: yes # Allow Hex 'F' for NUMERIC test of signed PACKED DECIMAL field hostsign: no # If yes, set WITH UPDATE clause as default for ACCEPT dest-item, # except if WITH NO UPDATE clause is used accept-update: no # If yes, set WITH AUTO clause as default for ACCEPT dest-item, # except if WITH TAB clause is used accept-auto: no # If yes, DISPLAYs and ACCEPTs are, by default, done on the CRT (i.e., # using curses). console-is-crt: no # If yes, allow redefinition of the current program's name. This prevents # its use in a prototype-format CALL/CANCEL statement. program-name-redefinition: yes # If yes, NO ECHO/NO-ECHO/OFF is the same as SECURE (hiding input with # asterisks, not spaces). no-echo-means-secure: no # Dialect features # Value: 'ok', 'warning', 'archaic', 'obsolete', 'skip', 'ignore', 'error', # 'unconformable' alter-statement: obsolete comment-paragraphs: obsolete call-overflow: archaic data-records-clause: obsolete debugging-mode: ok use-for-debugging: obsolete listing-statements: skip # may be a user-defined word title-statement: skip # may be a user-defined word entry-statement: ok goto-statement-without-name: obsolete label-records-clause: obsolete memory-size-clause: obsolete move-noninteger-to-alphanumeric: error move-figurative-constant-to-numeric: archaic move-figurative-quote-to-numeric: obsolete multiple-file-tape-clause: obsolete next-sentence-phrase: archaic odo-without-to: warning padding-character-clause: obsolete section-segments: ignore stop-literal-statement: obsolete stop-identifier-statement: obsolete synchronized-clause: ok top-level-occurs-clause: ok value-of-clause: obsolete numeric-boolean: ok hexadecimal-boolean: ok national-literals: ok hexadecimal-national-literals: ok acu-literals: unconformable word-continuation: warning not-exception-before-exception: ok accept-display-extensions: ok renames-uncommon-levels: ok constant-01: ok constant-78: ok program-prototypes: ok reference-out-of-declaratives: warning numeric-value-for-edited-item: ok incorrect-conf-sec-order: warning define-constant-directive: archaic # use complete word list; synonyms and exceptions are specified below reserved-words: default # not-reserved: # Value: Word to be taken out of the reserved words list not-reserved: TERMINAL # reserved: # Entries of the form word-1=word-2 define word-1 as an alias for default # reserved word word-2. No spaces are allowed around the equal sign. reserved: AUTO-SKIP=AUTO reserved: AUTOTERMINATE=AUTO reserved: BACKGROUND-COLOUR=BACKGROUND-COLOR reserved: BEEP=BELL reserved: BINARY-INT=BINARY-LONG reserved: BINARY-LONG-LONG=BINARY-DOUBLE reserved: EMPTY-CHECK=REQUIRED reserved: EQUALS=EQUAL reserved: FOREGROUND-COLOUR=FOREGROUND-COLOR reserved: INITIALISE=INITIALIZE reserved: INITIALISED=INITIALIZED reserved: LENGTH-CHECK=FULL reserved: ORGANISATION=ORGANIZATION reserved: SYNCHRONISED=SYNCHRONIZED reserved: TIMEOUT=TIME-OUT
Once GnuCOBOL programs have been compiled into either directly-executable programs (created via the-xswitch) or dynamically-loadable libraries (created via the-mswitch), those programs may be executed from any shell environment. The exact manner in which the two are executed will differ, as described in the upcoming sections.
GnuCOBOL programs compiled with the-xswitch
On Unix, OSX, or Windows/Cygwin builds, the-xswitch switch will generate an executable binary file, usually with no particular extension unless one is explicitly requested of the compiler via the-oswitch
On a UNIX system this means the programs may be executed from a command shell such as bash, csh, ksh and so forth. When a GnuCOBOL program runs on a Windows system, it runs within a console window (i.e. "cmd.exe"). OSX versions of GnuCOBOL programs run within a "terminal.app" window.
Interactions between the program and the user will take place using the standard input, standard output and standard error streams. Any screen section I/O performed by the program will take place within the command shell "window".
Direct program execution syntax is as follows:
[path]program [arguments]For example:
/usr/local/printaccount ACCT=6625378C:\Users\Me\Documents\Programs\printaccount.exe ACCT=6625378As discussed previously, dynamically-loadable libraries are created via the compiler’s-mswitch. Once so created, the program(s) in these libraries are executed from the command line (via the GnuCOBOLcobcrunutility), or as dynamically-loadable subprograms.
It is possible to generate executable modules for all GnuCOBOL programs, not just subprograms, by choosing to use the-mswitch
Some may prefer to compile their GnuCOBOL main programs into these dynamically-loadable modules in the interests of using the same general compilation command for all programs without having to think "Is it a main program or a subprogram?".
Main programs compiled in this manner should be executed as follows:
[path]cobcrun program [arguments]Do not specify the ".so" or ".dll" extension on the program name. The program value must exactly match the primary entry-point name of the main program (including upper- and lower-case letters), unless you are planning on using "Call Folding" (see Dynamically Loaded Subprograms).
The general usage and syntax of cobcrun is as follows as issued by running cobcrun -h (or –help) :
COBOL driver program for GnuCOBOL modules
Usage: cobcrun [options] PROGRAM [parameter ...]
or: cobcrun options
Options:
-h, -help display this help and exit
-V, -version display cobcrun and runtime version and exit
-i, -info display runtime information (build/environment)
-c <file>, -config=<file> set runtime configuration from <file>
-r, -runtime-conf display current runtime configuration
(value and origin for all settings)
-M <module>, -module=<module> set entry point module name and/or load path
where -M module prepends any directory to the
dynamic link loader library search path
and any basename to the module preload list
(COB_LIBRARY_PATH and/or COB_PRELOAD)
Here are two examples of usingcobcrun First, on a Unix, OSX or Windows/Cygwin system:
cd /usr/local cobcrun printaccount acct=6625378
Or, on a Native Windows or Windows/MinGW system:
cd C:\Users\Me\Documents\Programs cobcrun printaccount.exe acct=6625378
Note how thecobcruncommand does not allow a path to be specified with the program name — the directory in which the programs dynamically loadable module exists must either be the current directory or must be defined in the current PATH.
Dynamically-loaded subprograms are executed (from a COBOL syntax point of view) just like any other subprograms. What makes them unique, however, is that they are loaded into memory only when they are actually used the first time during the execution of a program.
When a dynamically-loadable module needs to be loaded (because it is not already in memory from a previous subprogram execution), the dynamically-loadable library will be sought in the same directory from which the main program was loaded. If it cannot be found there, each directory named in the
The process of locating dynamically-loadable modules is case-sensitive on UNIX systems;CALL "dynsub"andCALL "DYNSUB"will both fail to locate theDynSub.solibrary on a UNIX system.
Windows implementations of GnuCOBOL may, or may not, be similarly case sensitive with regard to library names, depending upon the Windows version and GnuCOBOL build options — it is safest to simply treat library names as case-sensitive in all environments.
It is possible, however, to automatically cause all library names to ’fold’ to upper-case by specifying the-ffold-callswitch
See Sub-Programming, for a complete discussion of sub-programming.
The following is a list of the various environment variables that can play a role in the execution of GnuCOBOL programs.
COB_DISPLAY_WARNINGS If set to a value of "Y", any run-time warnings (such as noting the implicit closing of open files when aGOBACKstatement (see GOBACK) orSTOPstatement (see STOP) with theRUNoption is executed) will be displayed. Any other value for this environment variable (including not setting the variable at all) will suppress such messages.
COB_LIBRARY_PATH At runtime, GnuCOBOL will attempt to locate and load any application dynamically-loadable libraries using from the directory in which the program executable was found or, if it wasn’t found there, using thePATHenvironment variable. If these library files could be somewhere else, specify the directory path using this variable.
COB_LOAD_CASE If set to eitherUPPERorLOWER this environment variable will internally convert referenced entry-point names to either upper- or lower-case before initiating searches for dynamically-loadable modules. TheUPPERandLOWERvalues of the environment variable are actually case-insensitive.
COB_PHYSICAL_CANCEL If set to "Y", "y" or "1", aCANCELstatement (see CANCEL) will physically unload a subprogram dynamically-loadable module.
If set to anything else, aCANCELstatement (see CANCEL) logically unloads a module so that subsequent use will re-initialize the module as if it had actually been reloaded, but the overhead of actually reloading the module will be avoided.
COB_PRE_LOAD If set to any non-null value, this variable will cause all dynamically-loadable libraries to be loaded when the program begins execution (rather than searching for and loading the module upon first use).
COB_SET_DEBUG If aUSE FOR DEBUGGING(see DECLARATIVES) section exists, the code within it will be disabled unless this environment variable is set to a value of "Y", "y" or "1".
COB_SET_TRACE If the-ftraceswitch
Tracing, if configured by one of the two switches described above, can also be controlled via the theREADY TRACEstatement (see READY TRACE) andRESET TRACEstatement (see RESET TRACE).
If COB_SET_TRACE is set to Y, then tracing will always occur regardless of the presence of READY TRACE or RESET TRACE so in effect they will have no action on program execution.
COB_SCREEN_ESC If set to any non-blank value, this variable allows aACCEPT screen-data-itemstatement (see ACCEPT screen-data-item) to detect the "Esc" key.
COB_SCREEN_EXCEPTIONS Setting this variable to any non-blank value will allow theACCEPT screen-data-itemstatement (see ACCEPT screen-data-item) to detect the pressing of the "Esc", "PgUp" and "PgDn" keys.
COB_SORT_MEMORY The value of this variable (an integer) will be used to define how much memory will be allocated for use in sorting. If the value is 1048576 or greater, that value will be used "as is" as the amount of memory (in bytes) to allocate. If the value is less than 1048576, the value will specify how many MB of memory will be allocated. The default sort memory amount is 128 MB.
COB_SWITCH_n (n=0 to 15); These environment variables correspond toSWITCH-0throughSWITCH-15 defined in theSPECIAL-NAMES(see SPECIAL-NAMES) paragraph. Setting them to "ON" will activate them; any other value turns them off.
COB_SYNC If set to a value of upper- or lower-case "p", this variable will force a file commit every time a file is written to (ensuring that data is immediately written to the file rather than retained in memory until a future commit occurs). This will slow-down update access to files, but will provide for better integrity in the event of a program failure.
COB_TRACE_FILE If set to any non-null value, this environment variable specifies the file to which all-ftraceswitch and-ftraceallswitch output will be written.
If this is NOT set to a value, all-ftraceswitch and-ftraceallswitch output will be written to STDERR, where it may be piped via a "2> filename" on the command that executes the program.
DB_HOME If your GnuCOBOL build uses the Berkeley Database (BDB) package, use this environment variable to specify the folder in which the lock management files to be associated with all non-SORT files opened by the program will be stored.ORGANIZATION INDEXED(see ORGANIZATION INDEXED) files will also have their data file allocated in the folder pointed to by this environment variable, if it exists.. Having this variable defined will activate record locking features on theREADstatement (see READ),REWRITEstatement (see REWRITE) andWRITEstatement (see WRITE). Even with DB_HOME, locking will not work withORGANIZATION SEQUENTIAL(see ORGANIZATION SEQUENTIAL),ORGANIZATION LINE SEQUENTIAL(see ORGANIZATION LINE SEQUENTIAL) or ORGANIZATION RELATIVE files with GnuCOBOL builds created for Windows/MinGW.ORGANIZATION INDEXEDlocks will work with Windows/MinGW + BDB and all locks will work for all file organizations with UNIX GnuCOBOL builds.
PATH The GnuCOBOL "bin" directory should be defined in the PATH.
TMPDIR TMP TEMP One of these environment variables must be set to a directory/folder appropriate to create temporary files in. They will be checked in the order shown. This will be used by theSORTstatement (see SORT) andMERGEstatement (see MERGE) to create temporary work files. You may also use this folder for any temporary files your application may require.
Also used during execution of programs is runtime.cfg also found in /usr/local/share/gnucobol/config for *nix and this file can also be changed to match your environment if needed.
When viewing, note the Default settings.
# GnuCOBOL runtime configuration
#
# Copyright (C) 2015-2017 Free Software Foundation, Inc.
# Written by Simon Sobisch, Ron Norman
#
# This file is part of the GnuCOBOL runtime.
#
#
## General instructions
#
# The initial runtime.cfg file is found in the $COB_CONFIG_DIR/config
# ( COB_CONFIG_DIR defaults to installdir/gnucobol ).
# The environment variable COB_RUNTIME_CONFIG may define a different runtime
# configuration file to read.
# If settings are included in the runtime environment file multiple times
# then the last setting value is used, no warning occurs.
# Settings via environment variables always take precedence over settings
# that are given in runtime configuration files. And the environment is
# checked after completing processing of the runtime configuration file(s)
# All values set to string variables or environment variables are checked
# for ${envvar} and replacement is done at the time of the setting.
# Any environment variable may be set with the directive setenv .
# Example: setenv COB_LIBARAY_PATH ${LD_LIBRARY_PATH}
# Any environment variable may be unset with the directive unsetenv
# (one var per line).
# Example: unsetenv COB_LIBRARY_PATH
# Runtime configuration files can include other files with the directive
# include.
# Example: include my-runtime-configuration-file
# To include another configuration file only if it is present use the directive
# includeif.
# You can also use ${envvar} inside this.
# Example: includeif ${HOME}/mygc.cfg
# If you want to reset a parameter to its default value use:
# reset parametername
# Most runtime variables have boolean values, some are switches, some have
# string values, integer values and some are size values.
# The boolean values will be evaluated as following:
# to true: 1, Y, ON, YES, TRUE (no matter of case)
# to false: 0, N, OFF
# A 'size' value is an integer optionally followed by K, M, or G for kilo, mega
# or giga.
# For convenience a parameter in the runtime.cfg file may be defined by using
# either the environment variable name or the parameter name.
# In most cases the environment variable name is the parameter name (in upper
# case) with the prefix COB_ .
#
## General environment
#
# Environment name: COB_DISABLE_WARNINGS
# Parameter name: disable_warnings
# Purpose: turn off runtime warning messages
# Type: boolean
# Default: false
# Example: DISABLE_WARNINGS TRUE
# Environment name: COB_ENV_MANGLE
# Parameter name: env_mangle
# Purpose: names checked in the environment would get non alphanumeric
# change to '_'
# Type: boolean
# Default: false
# Example: ENV_MANGLE TRUE
# Environment name: COB_SET_TRACE
# Parameter name: set_trace
# Purpose: to enable to COBOL trace feature
# Type: boolean
# Default: false
# Example: SET_TRACE TRUE
# Environment name: COB_TRACE_FILE
# Parameter name: trace_file
# Purpose: to define where COBOL trace output should go
# Type: string
# Default: stderr
# Example: TRACE_FILE ${HOME}/mytrace.log
# Environment name: COB_CURRENT_DATE
# Parameter name: current_date
# Purpose: specify an alternate Date/Time to be returned to ACCEPT clauses
# this is used for testing purposes or to tweak a missing offset
# partial setting is allowed
# Type: numeric string in format YYYYDDMMHH24MISS or date string
# Default: the operating system date is used
# Example: COB_CURRENT_DATE "2016/03/16 16:40:52"
# current_date YYYYMMDDHHMMSS+01:00
#
## Call environment
#
# Environment name: COB_LIBRARY_PATH
# Parameter name: library_path
# Purpose: paths for dynamically-loadable modules
# Type: string
# Note: the default paths .:/installpath/extras are always
# added to the given paths
# Example: LIBRARY_PATH /opt/myapp/test:/opt/myapp/production
# Environment name: COB_PRE_LOAD
# Parameter name: pre_load
# Purpose: modules that are loaded during startup, can be used
# to CALL COBOL programs or C functions that are part
# of a module library
# Type: string
# Note: the modules listed should NOT include extensions, the
# runtime will use the right ones on the various platforms,
# COB_LIBRARY_PATH is used to locate the modules
# Example: PRE_LOAD COBOL_function_library:external_c_library
# Environment name: COB_LOAD_CASE
# Parameter name: load_case
# Purpose: resolve ALL called program names to UPPER or LOWER case
# Type: Only use UPPER or LOWER
# Default: if not set program names in CALL are case sensitive
# Example: LOAD_CASE UPPER
# Environment name: COB_PHYSICAL_CANCEL
# Parameter name: physical_cancel
# Purpose: physically unload a dynamically-loadable module on CANCEL,
# this frees some RAM and allows the change of modules during
# run-time but needs more time to resolve CALLs (both to
# active and not-active programs)
# Alias: default_cancel_mode, LOGICAL_CANCELS (0 = yes)
# Type: boolean (evaluated for true only)
# Default: false
# Example: PHYSICAL_CANCEL TRUE
#
## File I/O
#
# Environment name: COB_VARSEQ_FORMAT
# Parameter name: varseq_format
# Purpose: declare format used for variable length sequential files
# - different types and lengths precede each record
# - 'length' is the data length & does not include the prefix
# Type: 0 means 2 byte record length (big-endian) + 2 NULs
# 1 means 4 byte record length (big-endian)
# 2 means 4 byte record length (local machine int)
# 3 means 2 byte record length (big-endian)
# Default: 0
# Example: VARSEQ_FORMAT 1
# Environment name: COB_FILE_PATH
# Parameter name: file_path
# Purpose: define default location where data files are stored
# Type: file path directory
# Default: . (current directory)
# Example: FILE_PATH ${HOME}/mydata
# Environment name: COB_LS_FIXED
# Parameter name: ls_fixed
# Purpose: Defines if LINE SEQUENTIAL files should be fixed length
# (or variable, by removing trailing spaces)
# Alias: STRIP_TRAILING_SPACES (0 = yes)
# Type: boolean
# Default: false
# Example: LS_FIXED TRUE
# Environment name: COB_LS_NULLS
# Parameter name: ls_nulls
# Purpose: Defines for LINE SEQUENTIAL files what to do with data
# which is not DISPLAY type. This could happen if a LINE
# SEQUENTIAL record has COMP data fields in it.
# Type: boolean
# Default: false
# Note: The TRUE setting will handle files that contain COMP data
# in a similar manner to the method used by Micro Focus COBOL
# Example: LS_NULL = TRUE
# Environment name: COB_SYNC
# Parameter name: sync
# Purpose: Should the file be synced to disk after each write/update
# Type: boolean
# Default: false
# Example: SYNC: TRUE
# Environment name: COB_SORT_MEMORY
# Parameter name: sort_memory
# Purpose: Defines how much RAM to assign for sorting data
# if this size is exceeded the SORT will be done
# on disk instead of memory
# Type: size but must be more than 1M
# Default: 128M
# Example: SORT_MEMORY 64M
# Environment name: COB_SORT_CHUNK
# Parameter name: sort_chunk
# Purpose: Defines how much RAM to assign for sorting data in chunks
# Type: size but must be within 128K and 16M
# Default: 256K
# Example: SORT_CHUNK 1M
#
## Screen I/O
#
# Environment name: COB_BELL
# Parameter name: bell
# Purpose: Defines how a request for the screen to beep is handled
# Type: FLASH, SPEAKER, FALSE, BEEP
# Default: BEEP
# Example: BELL SPEAKER
# Environment name: COB_REDIRECT_DISPLAY
# Parameter name: redirect_display
# Purpose: Defines if DISPLAY output should be sent to 'stderr'
# Type: boolean
# Default: false
# Example: redirect_display Yes
# Environment name: COB_SCREEN_ESC
# Parameter name: screen_esc
# Purpose: Enable handling of ESC key during ACCEPT
# Type: boolean
# Default: false
# Note: is only evaluated if COB_SCREEN_EXCEPTIONS is active
# Example: screen_esc Yes
# Environment name: COB_SCREEN_EXCEPTIONS
# Parameter name: screen_exceptions
# Purpose: enable exceptions for function keys during ACCEPT
# Type: boolean
# Default: false
# Example: screen_exceptions Yes
# Environment name: COB_TIMEOUT_SCALE
# Parameter name: timeout_scale
# Purpose: specify translation in milliseconds for ACCEPT clauses
# BEFORE TIME value / AFTER TIMEOUT
# Type: integer
# 0 means 1000 (Micro Focus COBOL compatible), 1 means 100
# (ACUCOBOL compatible), 2 means 10, 3 means 1
# Default: 0
# Example: timeout_scale 3
# Environment name: COB_INSERT_MODE
# Parameter name: insert_mode
# Purpose: specify default insert mode for ACCEPT; 0=off, 1=on
# Type: boolean
# Default: false
# Note: also sets the cursor type (if available)
# Example: insert_mode Y
# Environment name: COB_LEGACY
# Parameter name: legacy
# Purpose: keep behaviour of former runtime versions, currently only
# for setting screen attributes for non input fields
# Type: boolean
# Default: not set
# Example: legacy true
# Environment name: COB_EXIT_WAIT
# Parameter name: exit_wait
# Purpose: to wait on main program exit if an extended screenio
# DISPLAY was issued without an ACCEPT following
# Type: boolean
# Default: true
# Example: COB_EXIT_WAIT off
# Environment name: COB_EXIT_MSG
# Parameter name: exit_msg
# Purpose: string to display if COB_EXIT_WAIT is processed, set to ''
# if no actual display but an ACCEPT should be done
# Type: string
# Default: 'end of program, please press a key to exit' (localized)
# Example: COB_EXIT_MSG ''
# Note: If you want to slightly speed up a program's startup time, remove all
# of the comments from the actual real file that is processed
Regardless of the manner in which a main program is executed (i.e. directly or viacobcrun, any arguments specified to the program may be retrieved via any of the following:
ACCEPT FROM COMMAND-LINE(see ACCEPT FROM COMMAND-LINE) PROCEDURE DIVISION CHAINING(see PROCEDURE DIVISION CHAINING) There are a number of built-in system subroutines included with GnuCOBOL.
Generally, these routines are intended to match those available in Micro Focus COBOL, ACUCOBOL and directly for GnuCOBOL.
It is recommended to change the CBL_OC routines to CBL_GC for forward compatability as at some point they will be removed as they are a hangover from Open Cobol.
Prefix explanation:
C$ --> ACU,
CBL_ --> MF,
CBL_GC_ (For backwards compatibility some routines are also available as
CBL_OC_, as well): but these wonderful extensions are *only* available
with GnuCOBOL.
These routines, all executed via their UPPER-CASE NAMES via theCALLstatement (see CALL), are capable of performing the following Functions:
Early versions of Micro Focus COBOL allowed programmers to access various runtime library routines by using a single two-digit hexadecimal number as the entry-point name. These were known as call-by-number routines. Over time, Micro Focus COBOL evolved, replacing most of the call-by-number routines with ones accessible using a more conventional call-by-name technique.
Most of the call-by-number routines have evolved into even more powerful call-by-name routines, many of which are supported by GnuCOBOL.
Some of the original call-by-number routines never evolved call-by-name equivalents; GnuCOBOL supports some of these routines.
The following sections describe the various built-in subroutines. ALL SUBROUTINE ARGUMENTS ARE MANDATORY EXCEPT WHERE EXPLICITLY NOTED TO THE CONTRARY. Any subroutine returning a value to theRETURN-CODEspecial register (see Special Registers) could utilize theRETURNINGclause on theCALLstatement to return the result back to the full-word binary data item of your choice.
CALL "C$CALLEDBY" USING prog-name-area ~~~~ ~~~~~
TheRETURN-CODEspecial register (see Special Registers) will be set to one of the following values:
| -1 | An error occurred. The <prog-name-area> contents will be unchanged. |
| 0 | The program callingC$CALLEDBYwas not called by any other program (in other words, it is a main program). The <prog-name-area> contents will be set entirely to spaces. |
| 1 | The program callingC$CALLEDBYwas indeed called by another program, and that program’s name has been saved in <prog-name-area>. |
CALL "C$CHDIR" USING directory-path, result ~~~~ ~~~~~
The return code of the operation is returned both in the <result> argument (any non-edited numeric identifier) as well as in theRETURN-CODEspecial register (see Special Registers). The return code of the operation will be either 0=Success or 128=failure.
The directory change remains in effect until the program terminates (in which the original current directory at the time the program was started will be automatically restored) or until anotherC$CHDIRor aCBL_CHANGE_DIRbuilt-in system subroutine (see CBL_CHANGE_DIR) is executed.
CALL "C$COPY" USING src-file-path, dest-file-path, 0 ~~~~ ~~~~~
Both file path arguments may be alphanumeric literals or identifiers.
The third argument is required, but is unused.
If the attempt to copy the file fails (for example, it or the destination directory doesn’t exist), theRETURN-CODEspecial register (see Special Registers) will be set to 128; on successful completion it will be set to 0.
CALL "C$DELETE" USING file-path, 0 ~~~~ ~~~~~
The second argument is required, but is unused.
If the attempt to delete the file fails (for example, it doesn’t exist), theRETURN-CODEspecial register (see Special Registers) will be set to 128; on successful completion it will be set to 0.
CALL "C$FILEINFO" USING file-path, file-info ~~~~ ~~~~~
01 File-Info.
05 File-Size-In-Bytes PIC 9(18) COMP.
05 Mod-YYYYMMDD PIC 9(8) COMP. *> Modification Date
05 Mod-HHMMSS00 PIC 9(8) COMP. *> Modification Time
The last two decimal digits in the modification time will always be 00.
If the subroutine is successful, a value of 0 will be returned in theRETURN-CODEspecial register (see Special Registers). Failure to retrieve the needed statistics on the file will cause aRETURN-CODEspecial register value of 35 to be passed back. Supplying less than two arguments will generate a 128RETURN-CODEspecial register value.
CALL "C$GETPID" ~~~~
There are no arguments to this routine.
CALL "C$JUSTIFY" USING data-item, "justification-type" ~~~~ ~~~~~
CALL "C$MAKEDIR" USING dir-path ~~~~ ~~~~~
Only the lowest-level directory (last) in the specified path can be created — all others must already exist. This subroutine will NOT behave as amkdir -p(Unix) ormkdir /p(Windows).
TheRETURN-CODEspecial register (see Special Registers) will be set to the return code of the operation; the value will be either 0=Success or 128=failure.
CALL "C$NARG" USING arg-count-result ~~~~ ~~~~~
When called from a main program, the returned value will always be 0.
CALL "C$PARAMSIZE" USING argument-number ~~~~ ~~~~~
The size is returned in theRETURN-CODEspecial register (see Special Registers).
If the specified argument does not exist, or an invalid argument number is specified, a value of 0 is returned.
CALL "C$PRINTABLE" USING data-item [ , char ] ~~~~ ~~~~~
If no <char> argument is provided, a period (".") will be used.
NOTE that CBL_GC_PRINTABLE replaces this although it is currently still supported for legacy reasons.
CALL "C$SLEEP" USING seconds-to-sleep ~~~~ ~~~~~
Sleep times less than 1 will be interpreted as 0, which immediately returns control to the calling program without any sleep delay.
CALL "C$TOLOWER" USING data-item, BY VALUE convert-length ~~~~ ~~~~~ ~~~~~
The <convert-length> argument must be specifiedBY VALUE(see CALL). Any characters in <data-item> after the <convert-length> point will remain unchanged.
If <convert-length> is negative or zero, no conversion will be performed.
CALL "C$TOUPPER" USING data-item, BY VALUE convert-length ~~~~ ~~~~~ ~~~~~
The <convert-length> argument must be specifiedBY VALUE(see CALL). Any characters in <data-item> after the <convert-length> point will remain unchanged.
If <convert-length> is negative or zero, no conversion will be performed.
CALL "CBL_AND" USING item-1, item-2, BY VALUE byte-length ~~~~ ~~~~~ ~~~~~
Old Old New Arg 1 Arg 2 Arg 2 Bit Bit Bit ===== ===== ===== 0 0 0 0 1 0 1 0 0 1 1 1
|
This subroutine performs a bit-by-bit logical AND operation between the left-most 8*<byte-length> corresponding bits of <item-1> and <item-2>, storing the resulting bit string into <item-2>. The truth table shown to the left documents the AND process. The <item-1> argument may be an alphanumeric literal or a data item and <item-2> must be a data item. The length of both <item-1> and <item-2> must be at least 8*<byte-length>. |
The <byte-length> argument may be a numeric literal or data item, and must be specified usingBY VALUE(see CALL).
Any bits in <item-2> after the 8*<byte-length> point will be unaffected.
A result of zero will be passed back in theRETURN-CODEspecial register (see Special Registers).
CALL "CBL_CHANGE_DIR" USING directory-path ~~~~ ~~~~~
The return code of the operation, which will be either 0=Success or 128=failure, is returned in theRETURN-CODEspecial register (see Special Registers). The directory change remains in effect until the program terminates (in which the original current directory at the time the program was started will be automatically restored) or until anotherCBL_CHANGE_DIRor aC$CHDIRbuilt-in system subroutine (see C$CHDIR) is executed.
CALL "CBL_CHECK_FILE_EXIST" USING file-path, file-info ~~~~ ~~~~~
The information is returned to the <file-info> argument, which is defined as the following 16-byte area:
01 file-info.
05 File-Size-In-Bytes PIC 9(18) COMP.
05 Mod-DD PIC 9(2) COMP. *> Modification Time
05 Mod-MO PIC 9(2) COMP.
05 Mod-YYYY PIC 9(4) COMP. *> Modification Date
05 Mod-HH PIC 9(2) COMP.
05 Mod-MM PIC 9(2) COMP.
05 Mod-SS PIC 9(2) COMP.
05 FILLER PIC 9(2) COMP. *> Always 00
If the subroutine is successful, a value of 0 will be returned in theRETURN-CODEspecial register (see Special Registers). Failure to retrieve the needed statistics on the file will cause aRETURN-CODEspecial register value of 35 to be passed back. Supplying less than two arguments will generate a 128RETURN-CODEspecial register value.
CALL "CBL_CLOSE_FILE" USING file-handle ~~~~ ~~~~~
If the file defined by the <file-handle> argument (aPIC X(4) USAGE COMP-Xdata item) was opened for output, an implicitCBL_FLUSH_FILEbuilt-in system subroutine (see CBL_FLUSH_FILE) will be performed before the file is closed.
If the subroutine is successful, a value of 0 will be returned in theRETURN-CODEspecial register (see Special Registers). Failure will cause aRETURN-CODEspecial register value of -1 to be passed back.
CALL "CBL_COPY_FILE" USING src-file-path, dest-file-path ~~~~ ~~~~~
Both arguments may be alphanumeric literals or identifiers.
If the attempt to copy the file fails (for example, it or the destination directory doesn’t exist), theRETURN-CODEspecial register (see Special Registers) will be set to 128; on successful completion it will be set to 0.
CALL "CBL_CREATE_DIR" USING dir-path ~~~~ ~~~~~
Only the lowest-level directory (last) in the specified path can be created — all others must already exist. This subroutine will NOT behave as amkdir -p(Unix) ormkdir /p(Windows).
TheRETURN-CODEspecial register (see Special Registers) will be set to the return code of the operation; the value will be either 0=Success or 128=failure.
CALL "CBL_CREATE_FILE" USING file-path, 2, 0, 0, file-handle ~~~~ ~~~~~
Arguments 2, 3 and 4 should be coded as the constant values shown.CBL_CREATE_FILEis actually a special-case of theCBL_OPEN_FILEbuilt-in system subroutine (see CBL_OPEN_FILE) routine — see that routine for a description of the meanings of arguments 2, 3 and 4.
A <file-handle> PIC X(4) USAGE COMP-X)will be returned, for use on any subsequentCBL_WRITE_FILEbuilt-in system subroutine (see CBL_WRITE_FILE) orCBL_CLOSE_FILEbuilt-in system subroutine (see CBL_CLOSE_FILE) calls.
The success or failure of the subroutine will be reported back in theRETURN-CODEspecial register (see Special Registers), with a value of -1 indicating an invalid argument and a value of 0 indicating success.
CALL "CBL_DELETE_DIR" USING dir-path ~~~~ ~~~~~
The only argument — <dir-path> (an alphanumeric literal or identifier) — is the name of the directory to be deleted.
Only the lowest-level directory (last) in the specified path will be deleted, and that directory must be empty to be deleted.
TheRETURN-CODEspecial register (see Special Registers) will be set to the return code of the operation; the value will be either 0=Success or 128=failure.
CALL "CBL_DELETE_FILE" USING file-path ~~~~ ~~~~~
If the attempt to delete the file fails (for example, it doesn’t exist), theRETURN-CODEspecial register (see Special Registers) will be set to 128; on successful completion it will be set to 0.
CALL "CBL_EQ" USING item-1, item-2, BY VALUE byte-length ~~~~ ~~~~~ ~~~~~
Old Old New Arg 1 Arg 2 Arg 2 Bit Bit Bit ===== ===== ===== 0 0 1 0 1 0 1 0 0 1 1 1
|
This subroutine performs a bit-by-bit comparison between the left-most 8*<byte-length> corresponding bits of <item-1> and <item-2>, storing the resulting bit string into <item-2>. The truth table shown to the left documents the EQ process. The <item-1> argument may be an alphanumeric literal or a data item and <item-2> must be a data item. The length of both <item-1> and <item-2> must be at least 8*<byte-length>. |
The <byte-length> argument may be a numeric literal or data item, and must be specified usingBY VALUE(see CALL).
Any bits in <item-2> after the 8*<byte-length> point will be unaffected.
A result of zero will be passed back in theRETURN-CODEspecial register (see Special Registers).
CALL "CBL_ERROR_PROC" USING function, program-pointer ~~~~ ~~~~~
The <function> argument must be a numeric literal or a 32-bit binary data item USAGE BINARY-LONG for example) with a value of 0 or 1. A value of 0 means that you will be registering ("installing") an error procedure while a value of 1 indicates you’re de-registering ("uninstalling") a previously-installed error procedure.
The <program-pointer> must be a data item with aUSAGE(see USAGE) ofPROGRAM-POINTERcontaining the address of your error procedure. This item should be given a value using theSET Program-Pointerstatement (see SET Program-Pointer). If the error procedure is written in GnuCOBOL, it must be a subroutine, not a user-defined function.
A success (0) or failure (non-0) result will be passed back in theRETURN-CODEspecial register (see Special Registers).
A custom error procedure will trigger when a runtime error condition is encountered. An error procedure may be registered by a main program or a subprogram, but regardless of from where it was registered, it applies to the overall program compilation group and will trigger when a runtime error occurs anywhere in the executable program. If the error procedure was defined by a subprogram, that program must be loaded at the time the error procedure is executed.
An error procedure may be used to take whatever actions might be warranted to display additional information or to gracefully close down work in progress, but it cannot prevent the termination of program execution; should the error procedure not issue its ownSTOP RUN control will return back to the standard error routine when the error procedure exits.
The code within the handler will be executed and — once the handler issues areturn if it was written in C, or anEXIT PROGRAMstatement (see EXIT) orGOBACKstatement, if it was written in GnuCOBOL, the system-standard error handling routine will be executed.
Only one user-defined error procedure may be in effect at any time.
The following is a sample GnuCOBOL program that registers an error procedure. The output of that program is shown as well. As as you can see, the error handler’s messages appear followed by the standard GnuCOBOL message.
1. IDENTIFICATION DIVISION. 2. PROGRAM-ID. DemoERRPROC. 3. ENVIRONMENT DIVISION. 4. DATA DIVISION. 5. WORKING-STORAGE SECTION. 6. 01 Err-Proc-Address USAGE PROGRAM-POINTER. 7. PROCEDURE DIVISION. 8. S1. 9. DISPLAY 'Program is starting' 10. SET Err-Proc-Address TO ENTRY 'ErrProc' 11. CALL 'CBL_ERROR_PROC' USING 0, Err-Proc-Address 12. CALL 'Tilt' *> THIS DOESN'T EXIST!!!! 13. DISPLAY 'Program is stopping' 14. STOP RUN 15. . 16. END PROGRAM DemoERRPROC. 17. 18. IDENTIFICATION DIVISION. 19. PROGRAM-ID. ErrProc. 20. PROCEDURE DIVISION. 21. 000-Main. 22. DISPLAY 'Error: ' FUNCTION EXCEPTION-LOCATION 23. DISPLAY ' ' FUNCTION EXCEPTION-STATEMENT 24. DISPLAY ' ' FUNCTION EXCEPTION-FILE 25. DISPLAY ' ' FUNCTION EXCEPTION-STATUS 26. DISPLAY '*** Returning to Standard Error Routine ***' 27. EXIT PROGRAM 28. . 29. END PROGRAM ErrProc.
When executed, this sample program generates the following console output.
E:\Programs\Demos>demoerrproc
Program is starting
Error: DemoERRPROC; S1; 12
CALL
00
EC-PROGRAM-NOT-FOUND
*** Returning to Standard Error Routine ***
DEMOERRPROC.cbl: 27: libcob: Cannot find module 'Tilt'
E:\Programs\Demos>
CALL "CBL_EXIT_PROC" USING function, program-pointer ~~~~ ~~~~~
The <function> argument must be a numeric literal or a 32-bit binary data item USAGE BINARY-LONG for example) with a value of 0 or 1. A value of 0 means that you will be registering ("installing") an exit procedure while a value of 1 indicates you’re deregistering ("uninstalling") a previously-installed exit procedure.
The <program-pointer> must be a data item with aUSAGE(see USAGE) ofPROGRAM-POINTERcontaining the address of your exit procedure.
A success (0) or failure (non-0) result will be passed back in theRETURN-CODEspecial register (see Special Registers).
An exit procedure, once registered, will trigger whenever aSTOP RUNstatement (see STOP) or aGOBACKstatement (see GOBACK) is executed anywhere in the program. The exit procedure may execute whatever code is desired to undertake an orderly shut down of the program. Once the exit procedure terminates by executing anEXIT PROGRAMstatement (see EXIT) or aGOBACKstatement, the system-standard program termination routine will be executed.
Only one user-defined exit procedure may be in effect at any time.
The following is a sample GnuCOBOL program that registers an exit procedure. The output of that program is shown as well.
IDENTIFICATION DIVISION.
PROGRAM-ID. demoexitproc.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Exit-Proc-Address USAGE PROGRAM-POINTER.
PROCEDURE DIVISION.
000-Register-Exit-Proc.
SET Exit-Proc-Address TO ENTRY "ExitProc"
CALL "CBL_EXIT_PROC" USING 0, Exit-Proc-Address
IF RETURN-CODE NOT = 0
DISPLAY 'Error: Could not register Exit Procedure'
END-IF
.
099-Now-Test-Exit-Proc.
DISPLAY
'Executing a STOP RUN...'
END-DISPLAY
GOBACK.
END PROGRAM demoexitproc.
IDENTIFICATION DIVISION.
PROGRAM-ID. ExitProc.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Display-Date PIC XXXX/XX/XX.
01 Display-Time PIC XX/XX/XX.
01 Now PIC X(8).
01 Today PIC X(8).
PROCEDURE DIVISION.
000-Main.
DISPLAY '*** STOP RUN has been executed ***'
ACCEPT Today FROM DATE YYYYMMDD
ACCEPT Now FROM TIME
MOVE Today TO Display-Date
MOVE Now TO Display-Time
INSPECT Display-Time REPLACING ALL '/' BY ':'
DISPLAY '*** ' Display-Date ' ' Display-Time ' ***'
GOBACK.
END PROGRAM ExitProc.
CALL "CBL_FLUSH_FILE" USING file-handle ~~~~ ~~~~~
This routine is non-functional in GnuCOBOL. It exists only to provide compatibility for applications that may have been developed for Micro Focus COBOL.
CALL "CBL_GC_FORK" USING Child-PID ~~~~ ~~~~~
CBL_GC_FORK allows you to fork the current COBOL process to a new one.
The current content of the processâ storage (including LOCAL-STORAGE) will be identical, any file handles get invalid in the new process, positions and file / record locks are only available to the original process.
This system routine is not available on Windows (exception: GCC on Cygwin).
Parameters: none Returns: PID (the child process gets â0â returned, the calling process gets the PID of the created children).
Negative values are returned for system dependand error codes and -1 if the function is not available on the current system.
CBL_GC_FORK allows you to fork the current COBOL process to a new one. The
current content of the processâ storage (including LOCAL-STORAGE) will be
identical, any file handles get invalid in the new process, positions and
file / record locks are only available to the original process.
This system routine is not available on Windows (exception: GCC on Cygwin).
Parameters: none Returns: PID (the child process gets â0â returned, the calling
process gets the PID of the created children). Negative values are returned for
system dependand error codes and -1 if the function is not available on the
current system.
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 CHILD-PID PIC S9(9) BINARY.
01 WAIT-STS PIC S9(9) BINARY.
PROCEDURE DIVISION.
CALL "CBL_GC_FORK" RETURNING CHILD-PID END-CALL
EVALUATE TRUE
WHEN CHILD-PID = ZERO
PERFORM CHILD-CODE
WHEN CHILD-PID > ZERO
PERFORM PARENT-CODE
WHEN CHILD-PID = -1
DISPLAY âCBL_GC_FORK is not available on the current'
' system!â
PERFORM CHILD-CODE
MOVE 0 TO CHILD-PID
PERFORM PARENT-CODE
WHEN OTHER
MULTIPLY CHILD-PID BY -1 END-MULTIPLY
DISPLAY âCBL_GC_FORK returned system error: â CHILD-PID
END-EVALUATE
STOP RUN.
CHILD-CODE.
CALL "C$SLEEP" USING 1 END-CALL
DISPLAY "Hello, I am the child"
MOVE 2 TO RETURN-CODE
PARENT-CODE.
DISPLAY "Hello, I am the parent"
CALL "CBL_GC_WAITPID" USING CHILD-PID RETURNING WAIT-STS
MOVE 0 TO RETURN-CODE
EVALUATE TRUE
WHEN WAIT-STS >= 0
DISPLAY âChild ended with status: â WAIT-STS
WHEN WAIT-STS = -1
DISPLAY âCBL_GC_WAITPID is not available on the '
'current system!â
WHEN WAIT-STS < -1
MULTIPLY -1 BY WAIT-STS END-MULTIPLY
DISPLAY âCBL_GC_WAITPID returned system error: â WAIT-STS
END-EVALUATE
CALL "CBL_GC_GETOPT" USING BY REFERENCE SHORTOPTIONS LONGOPTIONS LONGIND
~~~~ ~~~~~
BY VALUE LONG-ONLY
BY REFERENCE RETURN-CHAR OPT-VAL CBL_GC_GETOPT realises the quite well-known option parser, getopt, for GnuCOBOL.
The usage of this system routine is described by the following example.
IDENTIFICATION DIVISION.
PROGRAM-ID. PROG.
DATA DIVISION.
WORKING-STORAGE SECTION.
78 SHORTOPTIONS VALUE "jkl".
01 LONGOPTIONS.
05 OPTIONRECORD OCCURS 2 TIMES.
10 OPTIONNAME PIC X(25).
10 HAS-VALUE PIC 9.
10 VALPOINT POINTER VALUE NULL.
10 RETURN-VALUE PIC X(4).
01 LONGIND PIC 99.
01 LONG-ONLY PIC 9 VALUE 1.
01 RETURN-CHAR PIC X(4).
01 OPT-VAL PIC X(10).
01 COUNTER PIC 9 VALUE 0.
We first need to define the necessary fields for getoptâs shortoptions (so),
longoptions (lo), longoption index (longind), long-only-option (long-only)
and also the fields for return values return-char and opt-val (arbitrary
size with trimming, see return codes).
The shortoptions are written down as an alphanumeric field (i.e., a string
with arbitrary size) as follows:
"ab:c::d"
This means we want getopt to look for shortoptions named a, b, c or d and
we demand an option value for b and we are accepting an optional one for c.
The longoptions are defined as a table of records with oname, has-value,
valpoint and val.
oname defines the name of a longoption.
has-value defines if an option value is demanded (has-val = 1), optional
(has-val = 2) or not required (has-val = 0).
valpoint is a pointer used to specify an address to save getoptâs return
value to. The pointer is optional. If it is NULL, getopt returns a value
as usual. If you use the pointer it has to point to a PIC X(4) field.
The field val is a PIC X(4) character which is returned if the longoption
was recognized.
The longoption structure is immutable! You can only vary the number of
records.
Now we have the tools to run CBL_GC_GETOPT within the procedure division.
PROCEDURE DIVISION.
MOVE "version" to OPTIONNAME (1).
MOVE 0 TO HAS-VALUE (1).
MOVE "V" TO RETURN-VALUE (1).
MOVE "verbose" TO OPTIONNAME (2).
MOVE 0 TO HAS-VALUE (2).
MOVE "V" TO RETURN-VALUE (2).
PERFORM WITH TEST AFTER UNTIL RETURN-CODE = -1
CALL âCBL_GC_GETOPTâ USING
BY REFERENCE SHORTOPTIONS LONGOPTIONS LONGIND
BY VALUE LONG-ONLY
BY REFERENCE RETURN-CHAR OPT-VAL
END-CALL
DISPLAY RETURN-CHAR END-DISPLAY
DISPLAY OPT-VAL END-DISPLAY
END-PERFORM
STOP RUN.
The example shows how we initialize all parameters and call the routine until
CBL_GC_GETOPT runs out of options and returns -1.
The return-char might contain the following:
regular character if an option was recognized
â ?â if we have an undefined or ambiguous option
â1â if we have a non-option (only if first byte of so is â-â)
â0â if valpoint != NULL and we are writing the return value to the specified
address
â-1â if we donât have any more options (or reach the first non-option if first
byte of so is â+â)
The return-codes of CBL_GC_GETOPT are:
1 if weâve got a non-option (only if first byte of so is â-â)
0 if valpoint != NULL and we are writing the return value to the specified
address
-1 if we donât have any more options (or reach the first non-option if first
byte of so is â+â)
2 if we have got an truncated option value in opt-val (because opt-val was
too small)
3 if we got a regular answer from getopt
CALL "CBL_GC_HOSTED" USING ARG-1 ARG-2 ~~~~ ~~~~~ Note replaces CBL_OC_HOSTED which is kept as a legacy item.
CBL_GC_HOSTED provides access to the following C hosted variables:
argc to binary-long by value
argv to pointer to char **
stdin, stdout, stderr to pointer
errno giving address of errno in pointer to binary-long, use based for more
direct access and conditional access to the following variables:
tzname pointer to pointer to array of two char pointers
timezone C long, will be seconds west of UTC
daylight C int, will be 1 during daylight savings
System will need to HAVE TIMEZONE defined for these to return anything
meaningful.
Attempts made when they are not available WILL return 1 from CBL GC HOSTED.
It returns 0 when match, 1 on failure, case matters as does length, "arg"
wonât match.
The usage of this system routine is described by the following example.
IDENTIFICATION DIVISION.
PROGRAM-ID. HOSTED.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Argc BINARY-LONG.
01 Argv POINTER.
01 Stdin POINTER.
01 Stdout POINTER.
01 Stderr POINTER.
01 Errno POINTER.
01 Err BINARY-LONG BASED.
01 Domain FLOAT-LONG VALUE 3.0.
01 Tzname POINTER.
01 Tznames POINTER BASED.
05 Tzs POINTER OCCURS 2.
01 Timezone BINARY-LONG.
01 Daylight BINARY-SHORT.
*>
PROCEDURE DIVISION.
call "CBL_GC_HOSTED" using stdin "stdin"
display "stdin : " stdin
call "feof" using by value stdin
display "feof stdin : " return-code
call "CBL_GC_HOSTED" using stdout "stdout"
display "stdout : " stdout
call "fprintf" using by value stdout by content "Hello" & x"0a"
call "CBL_GC_HOSTED" using stderr "stderr"
display "stderr : " stderr
call "fprintf" using by value stderr by content "on err" & x"0a"
call "CBL_GC_HOSTED" using argc "argc"
display "argc : " argc
call "CBL_GC_HOSTED" using argv "argv"
display "argv : " argv
call "args" using by value argc argv
call "CBL_GC_HOSTED" using errno "errno"
display "&errno : " errno
set address of err to errno
display "errno : " err
call "acos" using by value domain
display "errno after acos(3.0): " err ", EDOM is 33"
call "CBL_GC_HOSTED" using argc "arg"
display "âargâ lookup : " return-code
call "CBL_GC_HOSTED" using null "argc"
display "null with argc : " return-code
display "argc is still : " argc
*> the following only returns zero if the system has HAVE_TIMEZONE set
call "CBL_GC_HOSTED" using daylight "daylight "
display "âtimezoneâ lookup : " return-code
if return-code not = 0
display "system doesnât has timezone"
else
display "timezone is : " timezone
call "CBL_GC_HOSTED" using daylight "daylight "
display "âdaylightâ lookup : " return-code
display "daylight is : " daylight
set environment "TZ" to "PST8PDT"
call static "tzset" returning omitted on exception
continue end-call
call "CBL_GC_HOSTED" using tzname "tzname"
display "âtznameâ lookup : " return-code
*> tzs(1) will point to z"PST" and tzs(2) to z"PDT"
if return-code equal 0 and tzname not equal null then
set address of tznames to tzname
if tzs(1) not equal null then
display "tzs #1 : " tzs(1)
end-if
if tzs(2) not equal null then
display "tzs #2 : " tzs(2)
end-if
end-if
end-if
goback.
end program hosted.
Note that the legacy name of this routine that starts with CBL_OC is deprecated, as is NANOSLEEP but will still work. It is recommended that all libary routines names starting with CBL_OC are replaced with CBL_GC to minimise issues.
CALL "CBL_GC_NANOSLEEP" USING nanoseconds-to-sleep ~~~~ ~~~~~ Note replaces CBL_OC_NANOSLEEP which is kept as a legacy item.
The effective granularity of <nanoseconds-to-sleep> values will depend upon the granularity of the system clock your computer is using and the timing granularity of the operating system that computer is running.
For example, You will not expect to see any difference whatsoever between values of 1, 100, 500 or 1000, but you should see a difference between values such as 250000000 and 500000000.
The <nanoseconds-to-sleep> argument is a numeric literal or data item.
There are one BILLION nanoseconds in a second, so if you wanted to put the program to sleep for 1/4 second you’d use a <nanoseconds-to-sleep> value of 250000000.
Note that the legacy name of this routine starts with CBL_OC is deprecated, as is HOSTED but will still work. It is recommended that all libary routines names starting with CBL_OC are replaced with CBL_GC to minimise issues.
CALL "CBL_GC_PRINTABLE" USING data-item [ , char ] ~~~~ ~~~~~ Note replaces C$PRINTABLE which is kept as a legacy item.
TheCBL_GC_PRINTABLEsubroutine converts the contents of the data-item specified as the first argument to printable characters.
Those characters that are deemed printable (as defined by the character set used by <data-item>) will remain unchanged, while those that are NOT printable will be converted to the character specified as the second argument.
If no <char> argument is provided, a period (".") will be used.
CALL "CBL_GC_WAITPID" USING ARG-1
~~~~ ~~~~~
RETURNING RET-STATUS
~~~~~~~~~ CBL_GC_WAITPID allows you to wait until another system process ended.
Additional you can check the processâ return code.
Parameters: none Returns: function-status / child-status Negative values
are returned for system dependand error codes and -1 if the function is not
available on the current system.
CALL "CBL_GC_WAITPID" USING CHILD-PID RETURNING WAIT-STS
MOVE 0 TO RETURN-CODE
DISPLAY âCBL_GC_WAITPID ended with status: â WAIT-STS
CALL "CBL_GET_CSR_POS" USING cursor-locn-buffer ~~~~ ~~~~~
The returned location data will be in binary form, and will be based upon starting values of 0, meaning that if the cursor is located at line 15, column 12 at the time this routine is called, a value of (14,11) will be returned.
The following is a typical <cursor-locn-buffer> definition:
01 CURSOR-LOCN-BUFFER.
05 CURSOR-LINE USAGE BINARY-CHAR.
05 CURSOR-COLUMN USAGE BINARY-CHAR.
Values of 1 (Line) and 1 (column) will be returned if GnuCOBOL was not generated to include screen I/O.
CALL "CBL_GET_CURRENT_DIR" USING BY VALUE 0,
~~~~ ~~~~~ ~~~~~
BY VALUE length,
~~~~~
BY REFERENCE buffer
~~~~~~~~~
The first argument is unused, but must be specified. It must be specifiedBY VALUE(see CALL).
The <length> argument must be specifiedBY VALUE The <buffer> argument must be specifiedBY REFERENCE
The value specified for the <length> argument (a numeric literal or data item) should not exceed the actual length of the <buffer> argument.
If the value specified for the <length> argument is LESS THAN the actual length of the <buffer> argument, the current directory path will be left-justified and space filled within the first <length> bytes of <buffer> — any bytes in <buffer> after that point will be unchanged.
If the routine is successful, a value of 0 will be returned to theRETURN-CODEspecial register (see Special Registers). If the routine failed because of a problem with an argument (such as a negative or 0 length), a value of 128 will result. Finally, if the 1st argument value is anything but zero, the routine will fail with a 129 value.
CALL "CBL_GET_SCR_SIZE" USING no-of-lines, no-of-cols ~~~~ ~~~~~
When the system is running in a windowed environment, this will be the sizing of the console window in which the program is executing. When the system is not running a windowing environment, the physical console screen attributes will be returned. In environments such as a Windows console window, where the logical size of the window may far exceed that of the physical console window, the size returned will be that of the physical console window. Two one-byte values will be returned — the first will be the current number of lines (rows) while the second will be the number of columns.
The returned size data will be in binary form.
The following are typical <no-of-lines> and <no-of-columns> definitions:
01 NO-OF-LINES USAGE BINARY-CHAR. 01 NO-OF-COLUMNS USAGE BINARY-CHAR.
GnuCOBOL run-time screen management must have been initialized prior to CALLing this routine in order to receive meaningful values. This means that aDISPLAY screen-data-itemstatement (see DISPLAY screen-data-item) or aACCEPT screen-data-itemstatement (see ACCEPT screen-data-item) must have been executed prior to executing theCALLstatement.
Zero values will be returned if the screen has not been initialized and values of 24 (lines) and 80 (columns) will be returned if GnuCOBOL was not generated to include screen I/O.
CALL "CBL_IMP" USING item-1, item-2, BY VALUE byte-length ~~~~ ~~~~~ ~~~~~
Old Old New Arg 1 Arg 2 Arg 2 Bit Bit Bit ===== ===== ===== 0 0 1 0 1 1 1 0 0 1 1 1
|
This subroutine performs a bit-by-bit logical "implies" process between the left-most 8*<byte-length> corresponding bits of <item-1> and <item-2>, storing the resulting bit string into <item-2>. The truth table shown to the left documents the IMP process. The <item-1> argument may be an alphanumeric literal or a data item and <item-2> must be a data item. The length of both <item-1> and <item-2> must be at least 8*<byte-length>. |
The <byte-length> argument may be a numeric literal or data item, and must be specified usingBY VALUE(see CALL).
Any bits in <item-2> after the 8*<byte-length> point will be unaffected.
A result of zero will be passed back in theRETURN-CODEspecial register (see Special Registers).
CALL "CBL_NIMP" USING item-1, item-2, BY VALUE byte-length ~~~~ ~~~~~ ~~~~~
Old Old New Arg 1 Arg 2 Arg 2 Bit Bit Bit ===== ===== ===== 0 0 0 0 1 0 1 0 1 1 1 0
|
This subroutine performs the negation of a bit-by-bit logical "implies" process between the left-most 8*<byte-length> corresponding bits of <item-1> and <item-2>, storing the resulting bit string into <item-2>. The truth table shown to the left documents the NIMP process. The <item-1> argument may be an alphanumeric literal or a data item and <item-2> must be a data item. The length of both <item-1> and <item-2> must be at least 8*<byte-length>. |
The <byte-length> argument may be a numeric literal or data item, and must be specified usingBY VALUE(see CALL).
Any bits in <item-2> after the 8*<byte-length> point will be unaffected.
A result of zero will be passed back in theRETURN-CODEspecial register (see Special Registers).
CALL "CBL_NOR" USING item-1, item-2, BY VALUE byte-length ~~~~ ~~~~~ ~~~~~
Old Old New Arg 1 Arg 2 Arg 2 Bit Bit Bit ===== ===== ===== 0 0 1 0 1 0 1 0 0 1 1 0
|
This subroutine performs the negation of a bit-by-bit logical "or" process between the left-most 8*<byte-length> corresponding bits of <item-1> and <item-2>, storing the resulting bit string into <item-2>. The truth table shown to the left documents the NOR process. The <item-1> argument may be an alphanumeric literal or a data item and <item-2> must be a data item. The length of both <item-1> and <item-2> must be at least 8*<byte-length>. |
The <byte-length> argument may be a numeric literal or data item, and must be specified usingBY VALUE(see CALL).
Any bits in <item-2> after the 8*<byte-length> point will be unaffected.
A result of zero will be passed back in theRETURN-CODEspecial register (see Special Registers).
CALL "CBL_NOT" USING item-1, BY VALUE byte-length ~~~~ ~~~~~ ~~~~~
The <item-1> argument must be a data item. The length of <item-1> must be at least 8*<byte-length>.
The <byte-length> argument may be a numeric literal or data item, and must be passed usingBY VALUE(see CALL).
Any bits in <item-1> after the 8*<byte-length> point will be unaffected.
A result of zero will be passed back in theRETURN-CODEspecial register (see Special Registers).
CALL "CBL_OPEN_FILE" USING file-path, access-mode, 0, 0, handle ~~~~ ~~~~~
The <file-path> argument is an alphanumeric literal or data-item.
The <access-mode> argument is a numeric literal or data item with a PIC X USAGE COMP-X (or USAGE BINARY-CHAR) definition; it specifies how you wish to use the file, as follows:
1 = input (read-only) 2 = output (write-only) 3 = input and/or output
The third and fourth arguments would specify a locking mode and device specification, respectively, but they’re not implemented in GnuCOBOL (currently, at least) — just specify each as 0.
The final argument (<handle>) is aPIC X(4) USAGE COMP-Xitem that will receive the handle to the file. That handle is used on all other byte-stream functions to reference this specific file.
ARETURN-CODEspecial register (see Special Registers) value of -1 indicates an invalid argument, while a value of 0 indicates success. A value of 35 means the file does not exist.
CALL "CBL_OR" USING item-1, item-2, BY VALUE byte-length ~~~~ ~~~~~ ~~~~~
Old Old New Arg 1 Arg 2 Arg 2 Bit Bit Bit ===== ===== ===== 0 0 0 0 1 1 1 0 1 1 1 1
|
This subroutine performs a bit-by-bit logical "or" process between the left-most 8*<byte-length> corresponding bits of <item-1> and <item-2>, storing the resulting bit string into <item-2>. The truth table shown to the left documents the OR process. The <item-1> argument may be an alphanumeric literal or a data item and <item-2> must be a data item. The length of both <item-1> and <item-2> must be at least 8*<byte-length>. |
The <byte-length> argument may be a numeric literal or data item, and must be specified usingBY VALUE(see CALL).
Any bits in <item-2> after the 8*<byte-length> point will be unaffected.
A result of zero will be passed back in theRETURN-CODEspecial register (see Special Registers).
CALL "CBL_READ_FILE" USING handle, offset, nbytes, flag, buffer ~~~~ ~~~~~
The <handle> argument PIC X(4) USAGE COMP-X must have been populated by a prior call toCBL_OPEN_FILEbuilt-in system subroutine (see CBL_OPEN_FILE).
The <offset> argument PIC X(8) USAGE COMP-X defines the location in the file of the first byte to be read. The first byte of a file is byte offset 0.
The <nbytes> argument PIC X(4) USAGE COMP-X specifies how many bytes (maximum) will be read. If the <flag> argument is specified as 128, the size of the file (in bytes) will be returned into the file offset argument (argument 2) upon completion. Not all operating system/GnuCOBOL environments may be able to retrieve file sizes in such cases, a value of zero will be returned. The only other valid value for flags is 0. This argument may be specified either as a numeric literal or as aPIC X USAGE COMP-Xdata item.
Upon completion, theRETURN-CODEspecial register (see Special Registers) will be set to 0 if the read was successful or to 10 if an "end-of-file" condition occurred. If a value of -1 is returned, a problem was identified with the subroutine arguments.
CALL "CBL_RENAME_FILE" USING old-file-path, new-file-path ~~~~ ~~~~~
The file specified by <old-file-path> will be "renamed" to the name specified as <new-file-path>. Each argument may be an alphanumeric literal or data item.
Despite what the name of this routine might make you believe, this routine is more than just a simple "rename" — it will actually move the file supplied as the 1st argument to the file specified as the 2nd argument. Think of it as a two-step sequence, first copying the <old-file-path> file to the <new-file-path> file and then a second step where the <old-file-path> is deleted.
If the attempt to move the file fails (for example, it doesn’t exist), theRETURN-CODEspecial register (see Special Registers) will be set to 128; on successful completion it will be set to 0.
CALL "CBL_TOLOWER" USING data-item, BY VALUE convert-length ~~~~ ~~~~~ ~~~~~
The <convert-length> argument must be specifiedBY VALUE(see CALL). It specifies how many (leading) characters in data-item will be converted — any characters after that will remain unchanged.
If <convert-length> is negative or zero, no conversion will be performed.
CALL "CBL_TOUPPER" USING data-item, BY VALUE convert-length ~~~~ ~~~~~ ~~~~~
The <convert-length> argument must be specifiedBY VALUE(see CALL). It specifies how many (leading) characters in data-item will be converted — any characters after that will remain unchanged.
If <convert-length> is negative or zero, no conversion will be performed.
CALL "CBL_WRITE_FILE" USING handle, offset, nbytes, 0, buffer ~~~~ ~~~~~
The <handle> argument PIC X(4) USAGE COMP-X must have been populated by a prior call to CBL_OPEN_FILE. The offset argument PIC X(4) USAGE COMP-X defines the location in the file of the first byte to be written to. The first byte of a file is byte offset 0.
The <nbytes> argument PIC X(4) USAGE COMP-X specifies how many bytes (maximum) will be written.
Currently, the only allowable value for the flags argument is 0. This argument may be specified either as a numeric literal or as aPIC X(1) USAGE COMP-Xdata item.
Upon completion, theRETURN-CODEspecial register (see Special Registers) will be set to 0 if the write was successful or to 30 if an I/O error condition occurred. If a value of -1 is returned, a problem was identified with the subroutine arguments.
CALL "CBL_XOR" USING item-1, item-2, BY VALUE byte-length ~~~~ ~~~~~ ~~~~~
Old Old New Arg 1 Arg 2 Arg 2 Bit Bit Bit ===== ===== ===== 0 0 0 0 1 1 1 0 1 1 1 0
|
This subroutine performs a bit-by-bit logical "exclusive or" process between the left-most 8*<byte-length> corresponding bits of <item-1> and <item-2>, storing the resulting bit string into <item-2>. The truth table shown to the left documents the XOR process. The <item-1> argument may be an alphanumeric literal or a data item and <item-2> must be a data item. The length of both <item-1> and <item-2> must be at least 8*<byte-length>. |
The <byte-length> argument may be a numeric literal or data item, and must be specified usingBY VALUE(see CALL).
Any bits in <item-2> after the 8*<byte-length> point will be unaffected.
A result of zero will be passed back in theRETURN-CODEspecial register (see Special Registers).
CALL "SYSTEM" USING command ~~~~ ~~~~~
A shell will be opened subordinate to the GnuCOBOL program issuing the call toSYSTEM
Output from the command (if any) will appear in the command window in which the GnuCOBOL program was executed.
On a Unix system, the shell environment will be established using the default shell program. This is also true when using a GnuCOBOL build created with and for OSX or the Cygwin Unix emulator.
With native Windows Windows/MinGW builds, the shell environment will be the Windows console window command processor (usually "cmd.exe") appropriate for the version of Windows you’re using.
To trap output from the executed command and process it within the GnuCOBOL program, use a pipe (>) to send the command output to a temporary file which you read from within the program once control returns.
CALL X"91" USING return-code, function-code, binary-variable-arg ~~~~ ~~~~~
The <return-code> argument must be a one-byte binary numeric data item USAGE BINARY-CHARis recommended). It will receive a value of 0 if the operation was successful, 1 otherwise.
The <function-code> argument must be either a numeric literal or a one-byte binary numeric data item USAGE BINARY-CHARis recommended).
The third argument — <variable-arg> — is defined differently depending upon the <function-code> value, as follows:
Sets and/or clears all eight of the COBOL switches (SWITCH-1 through SWITCH-8). See SPECIAL-NAMES, for an explanation of those switches.
The <variable-arg> argument should be anOCCURS 8 TIMEStable ofUSAGE BINARY-CHAR
Each occurrence that is set to a value of zero prior to theCALL X"91"will cause the corresponding switch to be cleared. Each occurrence set to 1 prior to theCALL X"91"will cause the corresponding switch to be set.
Values other than 0 or 1 will be ignored.
Reads all eight of the COBOL switches (SWITCH-1 through SWITCH-8)
The <variable-arg> argument should be anOCCURS 8 TIMEStable ofUSAGE BINARY-CHAR
Each of the 1st eight occurrences of the array will be set to either 0 or 1 — 1 if the corresponding switch is set, 0 otherwise.
Retrieves the number of arguments passed to the program executing the CALL X"91", saving that number into the <variable-arg> argument. That should be a binary numeric data item USAGE BINARY-CHARis recommended).
CALL X"E4" ~~~~
CALL X"E5" ~~~~
CALL X"F4" USING byte, table ~~~~ ~~~~~
The <byte> data item need be only a single byte in size. If it is longer, the excess will be unaffected by this subroutine.
The <table> data item must be at least 8 bytes long. If it is longer, the excess will be ignored by this subroutine.
Typically, table is defined similarly to the following:
01 Table-Arg.
05 Each-Byte OCCURS 8 TIMES USAGE BINARY-CHAR.
CALL X"F5" USING byte, table ~~~~ ~~~~~
The <byte> data item need be only a single byte in size. If it is longer, the excess will be unaffected by this subroutine.
The <table> data item must be at least 8 bytes long. If it is longer, the excess will be ignored by this subroutine.
Typically, table is defined similarly to the following:
01 Table-Arg.
05 Each-Byte OCCURS 8 TIMES USAGE BINARY-CHAR.
By default, the GnuCOBOL compiler will truncate binary data items to the precision indicated by theirPICTURE(see PICTURE) clause, if they have one. This applies to COMP, BINARY and COMP-4 items Only. The fact is, however, that binary truncation has a significant effect on the performance of GnuCOBOL programs. When binary truncation is in effect, arithmetic operations performed against all types of numeric data items (evenUSAGE DISPLAY are slowed down.
Before continuing, it’s worth making the point that we’re NOT talking about astronomical performance degradations here. Today’s computers are FAST, and a user sitting at the keyboard, running a GnuCOBOL program is unlikely to notice. BUT … if you have a GnuCOBOL program that has to process large amounts of data, performing some significant "number crunching" against that data as it goes, the impact of truncation could become noticeable.
The following program compares the performance of performing arithmetic operations (in a totally non-scientific, non-rigorous way) against data items with aUSAGE(see USAGE) ofDISPLAYCOMPandBINARY-LONG It was actually my intent when I first wrote the program to merely demonstrate the relative performance differences between different types of numeric data storage, and it certainly met that objective.
IDENTIFICATION DIVISION.
PROGRAM-ID. DEMOMATH.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Begin-Time.
05 BT-HH PIC 9(2).
05 BT-MM PIC 9(2).
05 BT-SS PIC 9(2).
05 BT-HU PIC 9(2).
01 Binary-Item BINARY-LONG SIGNED VALUE 0.
01 Comp-Item COMP PIC S9(9) VALUE 0.
01 Display-Item DISPLAY PIC S9(9) VALUE 0.
01 End-Time.
05 ET-HH PIC 9(2).
05 ET-MM PIC 9(2).
05 ET-SS PIC 9(2).
05 ET-HU PIC 9(2).
78 Repeat-Count VALUE 10000000.
01 Time-Diff PIC ZZ9.99.
PROCEDURE DIVISION.
010-Test-Usage-DISPLAY.
ACCEPT Begin-Time FROM TIME
PERFORM Repeat-Count TIMES
ADD 7 TO Display-Item
END-PERFORM
PERFORM 100-Determine-Time-Diff
DISPLAY 'USAGE DISPLAY: ' Time-Diff ' SECONDS'
.
020-Test-Usage-COMP.
ACCEPT Begin-Time FROM TIME
PERFORM Repeat-Count TIMES
ADD 7 TO Comp-Item
END-PERFORM
PERFORM 100-Determine-Time-Diff
DISPLAY 'USAGE COMP: ' Time-Diff ' SECONDS'
.
040-Test-Usage-BINARY.
ACCEPT Begin-Time FROM TIME
PERFORM Repeat-Count TIMES
ADD 7 TO Binary-Item
END-PERFORM
PERFORM 100-Determine-Time-Diff
DISPLAY 'USAGE BINARY: ' Time-Diff ' SECONDS'
.
099-Done.
STOP RUN
.
100-Determine-Time-Diff.
ACCEPT End-Time FROM TIME
COMPUTE Time-Diff =
( (ET-HH * 360000 + ET-MM * 6000 + ET-SS * 100 + ET-HU)
- (BT-HH * 360000 + BT-MM * 6000 + BT-SS * 100 + BT-HU) )
/ 100
.
Each data item has 7 added to it ten million times.
The time (to one-one-hundredth of a second) will be retrieved before and after each test and the difference between the two is displayed. This is why the computations were done so many times — it was to make sure the timing was "measurable" with only a 1/100 second "stopwatch".
I also ran the tests multiple times, just to make sure I had consistent results (I did). Like I mentioned earlier, this is not a rigorous, scientific benchmark of numeric performance; it’s just a quick-and-dirty comparison.
Here are the results:
Test 1: USAGE DISPLAY: 1.72 SECONDS USAGE COMP: 0.62 SECONDS USAGE BINARY: 0.02 SECONDS Test 2: USAGE DISPLAY: 1.69 SECONDS USAGE COMP: 0.61 SECONDS USAGE BINARY: 0.02 SECONDS Test 3: USAGE DISPLAY: 1.69 SECONDS USAGE COMP: 0.65 SECONDS USAGE BINARY: 0.02 SECONDS
The results I saw here were consistent with those that would have been obtained from most of the COBOL implementations I have ever worked with —USAGE COMPhas a significant performance advantage overUSAGE DISPLAYandUSAGE BINARY-LONG(and presumably the otherBINARY-xxxusages as well) perform identically, within the measurement tolerances of the test.
Imagine my surprise, however, when I discovered that the use of-fnotruncswitch also made a difference:
Test 4: USAGE DISPLAY: 1.72 SECONDS USAGE COMP: 0.07 SECONDS USAGE BINARY: 0.02 SECONDS Test 5: USAGE DISPLAY: 1.72 SECONDS USAGE COMP: 0.07 SECONDS USAGE BINARY: 0.02 SECONDS Test 6: USAGE DISPLAY: 1.73 SECONDS USAGE COMP: 0.06 SECONDS USAGE BINARY: 0.02 SECONDS
As you can see, there was a huge drop inUSAGE COMPtimings by turning off truncation. As a result, I see absolutely no reason whatsoever why the-fnotruncswitch option shouldn’t be used on all GnuCOBOL compilations.
If you want to squeeze every last bit of performance out of your GnuCOBOL programs, don’t forget to investigate the-Oswitch
Test 7: cobc -x demomath.cbl -O2;demomath USAGE DISPLAY: 1.68 SECONDS USAGE COMP: 0.60 SECONDS USAGE BINARY: 0.00 SECONDS Test 8: cobc -x demomath.cbl -fnotrunc -O2;demomath USAGE DISPLAY: 1.67 SECONDS USAGE COMP: 0.01 SECONDS USAGE BINARY: 0.00 SECONDS
All tests above carried out under Linux with a AMD FX8350 under very low loading prior to the test. I would have also tried on a i7-7700 but that is under Windows 10 and I do not have a GC version on it - Vince.
Simply stated, a ’Subprogram’
When program "A" invokes subprogram "B" as a ’Subroutine’
When program "A" invokes program "B" as a ’User-Defined Function’
In either instance, program "A" is referred to as the ’Calling Program’
A program written in the C programming language may serve as either the calling or called program too. A called program may act as a calling program to another called program. When a calling program does not serve as a called program to any program, that calling program is known as a ’Main Program’
Both subroutines and user-defined functions may return a value. The value they return must be an integer in the range -2147483648 to +2147483647. This value will be available in theRETURN-CODEspecial register (see Special Registers) and also as the value of the data item specified on theRETURNING(see CALL) clause of a subroutine’s CALL.
Subprograms (either subroutines or user-defined functions) can be implemented in three different ways.
These are subprograms that are coded as the only COBOL program in their Compilation Unit (see Compilation Unit).
These are subprograms which occur in the same Compilation Unit as a main program and/or other subprograms. Each contained subprogram is separated from the next via anEND PROGRAMmarker line. As an example…
IDENTIFICATION DIVISION. PROGRAM-ID. SUB1. … END PROGRAM SUB1. IDENTIFICATION DIVISION. PROGRAM-ID. SUB2. … END PROGRAM SUB2.
Program source code may be concatenated as shown here, provided anEND PROGRAMmarker naming thePROGRAM-IDof the just-completed program is used to separate one program from another.
There’s no reason that user-defined functions cannot be included too — they’ll just haveFUNCTION-ID and will be ended byEND FUNCTIONmarkers.
The last program in any GnuCOBOL source file need not have anENDmarker.
When multiple programs occur in a source file, it is assumed that the programs are related to one another in that they will be CALLed or executed as functions from the others.
It is also possible to create source files where GnuCOBOL programs are nested inside each other. Take for example these four GnuCOBOL programs:
IDENTIFICATION DIVISION. PROGRAM-ID. PROG1. … IDENTIFICATION DIVISION. PROGRAM-ID. PROG2. … IDENTIFICATION DIVISION. PROGRAM-ID. PROG3. … END PROGRAM PROG3. END PROGRAM PROG2. IDENTIFICATION DIVISION. PROGRAM-ID. PROG4. … END PROGRAM PROG4. END PROGRAM PROG1.
Here we see that PROG2 is nested inside of PROG1 because there is noEND PROGRAMmarker separating them. This means that data items or files defined within PROG1 can be used within PROG2 simply by attaching theGLOBAL(see GLOBAL) attribute to them back in PROG1 when they are defined.
Similarly, since there is noEND PROGRAMmarker separating PROG3 from PROG2, it is possible for PROG3 to accessGLOBALfiles and data items defined within PROG2. Since PROG2 is nested within PROG1, anyGLOBALresources defined within PROG1 will be available to PROG3 as well.
The twoEND PROGRAMmarkers for PROG3 and PROG2 (note their sequence) mean that PROG4 is nested within PROG1 only. It will not have access to anyGLOBALresources defined within either PROG2 or PROG3.
TheEND PROGRAM PROG1.marker, since it is the last line in the source file, is entirely optional.
Any subroutine may have multiple entry-points defined within it. This means the subroutine could be called either via aCALL '<program-id>'or aCALL '<entry-point>'statement. There may be any number of alternate entry-points defined within a subroutine.
Alternate entry-points provide multiple ways in which the same subroutine may be called; presumably, each entry-point will provide some different functionality to the calling program. For example, if you wished to write a subroutine that manipulates "student" records in a database, you might have the primary entry-point name retrieve a student record from the database, while the alternate entry pointsAdd-StudentUpdate-StudentandDelete-Studentcould provide the alternate functions implied by their entry-point names.
The alternative to using multiple entry points in your subroutine, by the way, would be to include an additional argument to the primary (and only) entry point of the subroutine; this new argument might be namedSTUDENT-FUNCTIONand might have values of "FETCH", "ADD", "UPDATE" or "DELETE".
The primary entry-point for any subroutine is always the first executable statement following anyDECLARATIVES(see DECLARATIVES) in the procedure division. The name of that entry-point (the name that will be called) is the subroutine’sPROGRAM-ID(see IDENTIFICATION DIVISION).
An alternate entry point is added to a subroutine using theENTRYstatement (see ENTRY).
When an alternate entry-point is called, execution within the subroutine will begin at the first executable statement following theENTRYstatement.
Any subprogram may be either statically or dynamically loaded into memory.
A ’Static Subprogram’
A ’Dynamic Subprogram’
GnuCOBOL subprograms may be created as either static or dynamic subprograms, as desired by the programmer.
To demonstrate, assume that a GnuCOBOL Main Program (whose code resides in the file "M.cbl") will be calling three subprograms, named "A", "B" and "C" (these are thePROGRAM-ID of the three subprograms, and their source code may be found in the files "A.cbl", "B.cbl" and "C.cbl", respectively.
Here is how these four programs would be compiled if the three subprograms are to be static:
cobc -x M.cbl A.cbl B.cbl C.cblThis command informs the compiler (cobc) that four programs are to be compiled (the first named on the command must always be the main program), and a single executable file is to be created (due to the-xswitch
Here is how the main program and the three subprograms could be compiled if the three subprograms are to be dynamic:
cobc -x M.cblcobc -m A.cbl B.cbl C.cblThese commands will create an executable file for the main program -xswitch) and three separate dynamically-loadable libraries -mswitch
cobc -m -b A.cbl B.cbl C.cblDynamically-loadable libraries are also known by the term dynamically-loadable modules — the two terms are synonymous.
Here are the rules about GnuCOBOL dynamically-loadable modules:
-bswitch is used in addition to-m If not, each subprogram will be compiled to a separate dynamically-loadable library. PROGRAM-IDorFUNCTION-ID or an alternate entry point name defined via theENTRYstatement (see ENTRY) of any one of the GnuCOBOL programs included in that module. CANCELstatement (see CANCEL). CANCELstatement), it’s list of entry-points remain available to the GnuCOBOL run-time library and subsequent re-executions of any of those entry points will be able to bypass the search (rule #4) as well as the "first-execution rule" (rule #3). Consult the documentation on the
When a subprogram is invoked, the flow of execution will differ slightly depending on whether the subprogram is a subroutine or a user-defined function.
When a subroutine isCALLd:
CALL '<entry-point>' USING ...to transfer control to the subroutine. CALL(see CALL). PROGRAM-ID(see IDENTIFICATION DIVISION) clause of the subprogram included theINITIAL DECLARATIVES(see DECLARATIVES) that might be present (if the subprogram was invoked using its primary entry-point name) or the first executable statement following theENTRYstatement (see ENTRY) naming the entry-point specified on theCALLif the subprogram was invoked using an alternate entry point. STOPstatement (see STOP) with theRUNoption, program execution ceases and control returns to the operating system or whatever execution shell invoked the main program. GOBACKstatement (see GOBACK) or theEXIT PROGRAMstatement (see EXIT). At this time: ENTRYstatement included aRETURNING (see Special Registers); this behaviour can be altered utilizing theCALL-CONVENTION(see SPECIAL-NAMES) feature to leaveRETURN-CODEunchanged. RETURNINGclause on theCALLstatement that invoked the subprogram, the value of theRETURNINGdata item in the subroutine is moved to that data item. If there was noRETURNINGspecified in the subroutine, the value of theRETURN-CODEspecial register is moved to that data item. CALLthat invoked the subprogram. When a user-defined function is executed:
DECLARATIVES(see DECLARATIVES) that might be present. STOPstatement (see STOP) with theRUNoption, program execution ceases and control returns to the operating system or whatever execution shell invoked the main program. GOBACKstatement (see GOBACK) or theEXIT FUNCTIONstatement (see EXIT). At this time: PROCEDURE DIVISION RETURNING(see PROCEDURE DIVISION RETURNING) clause is moved to theRETURN-CODEspecial register (see Special Registers). RETURN-CODEspecial register will be used for the function’s value. Data items defined in a calling program may be passed to either type of called program (subroutine or user-defined function) as arguments.
Arguments must be described in both the calling and called programs, and while they don’t need to have the same names in both programs, they should be described in an identical manner with regard to the following characteristics:
PICTURE(see PICTURE) (including both type and length) SIGN(see SIGN) SYNCRONIZED(see SYNCRONIZED) USAGE(see USAGE) A subroutine may be passed a maximum of 36 arguments; if you build the GnuCOBOL software yourself from the distributed source, you CAN change this value by altering the defined value ofCOB_MAX_FIELD_PARAMSin the "common.h" header file. There is no built-in GnuCOBOL limit to how many arguments a user-defined function may be passed.
Whether or not changes made to an argument within a subroutine will be "visible" to the calling program depends on how the argument was passed. There are three ways in which arguments may be passed from a calling program to a subroutine, as defined by the use of optionalBYclauses in theCALL(see CALL) statement’s list of arguments.
As an example, the following statement passes three arguments to a subroutine — each argument is passed differently.
CALL "subroutine" USING BY REFERENCE arg-1
BY CONTENT arg-2
BY VALUE arg-3
END-CALL
The three ways arguments are passed are as follows.
BY REFERENCEWhen a subroutine argument is passedBY REFERENCE
BY CONTENTWhen a subroutine is passed an argumentBY CONTENT
BY VALUEPassing a subroutine argumentBY VALUE
The first two ways in which arguments may be passed BY REFERENCEandBY CONTENT are intended for use when a GnuCOBOL program is being called, while the first and third BY REFERENCEandBY VALUE are intended for use when a C program is being called. You can useBY VALUEarguments when calling GnuCOBOL subroutines, but remember that those arguments are limited to being a numeric binary data item.
Arguments to user-defined functions are always passedBY REFERENCE
When coding a GnuCOBOL subprogram (a subroutine or user-defined function), all arguments to the subprogram must be defined in the subprogram’s linkage section.
These arguments must be explicitly included on thePROCEDURE DIVISION USING(see PROCEDURE DIVISION USING) clause that lists the arguments in the sequence in which they will be passed to the subprogram.
These arguments described in thePROCEDURE DIVISION USINGclause may each be defined as eitherBY REFERENCE if the calling program is passing them eitherBY REFERENCE
By default, all arguments are assumed to beBY REFERENCEunless explicitly stated otherwise on the procedure division header.
Arguments to a user-defined function are always to be specified asBY REFERENCE(either explicitly or by not using anyBY.
If the subprogram returns a value, the data item in which the value is returned must also be defined in the subprogram’s linkage section, with aUSAGE(see USAGE) ofBINARY-LONG SIGNED or it’s equivalent.
Another way in which a data item may be shared between a calling program ("A") and a called program ("B") is by defining the data item in the calling program and attaching theGLOBAL(see GLOBAL) clause to it so that it may be used within the called program. In order for this to work, program "B" (the one called by program "A") must be a nested subprogram within program "A".
Here’s a small example:
IDENTIFICATION DIVISION.
PROGRAM-ID. DemoGLOBAL.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Arg GLOBAL PIC X(10).
PROCEDURE DIVISION.
000-Main.
MOVE ALL "X" TO Arg
CALL "DemoSub" END-CALL
DISPLAY "DemoGLOBAL: " Arg END-DISPLAY
GOBACK
.
IDENTIFICATION DIVISION.
PROGRAM-ID. DemoSub.
PROCEDURE DIVISION.
000-Main.
MOVE ALL "*" TO Arg.
GOBACK
.
END PROGRAM DemoSub.
END PROGRAM DemoGLOBAL.
When the program runs, it produces the output:
DemoGLOBAL: **********
The final way in which a data item may be shared between a calling program ("A") and a called program ("B") is by defining the data item (with the same name) in both programs and attaching theEXTERNAL(see EXTERNAL) clause to it (again, in both programs). This approach works regardless of whether the called program is nested within the calling program or not. It also works even if the two programs are compiled separately.
Here’s a demonstration:
IDENTIFICATION DIVISION.
PROGRAM-ID. DemoEXTERNAL.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Arg EXTERNAL PIC X(10).
PROCEDURE DIVISION.
000-Main.
MOVE ALL "X" TO Arg
CALL "DemoSub" END-CALL
DISPLAY "DemoEXTERNAL: " Arg END-DISPLAY
GOBACK
.
END PROGRAM DemoEXTERNAL.
IDENTIFICATION DIVISION.
PROGRAM-ID. DemoSub.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Arg EXTERNAL PIC X(10).
PROCEDURE DIVISION.
000-Main.
MOVE ALL "*" TO Arg.
GOBACK
.
END PROGRAM DemoSub.
When the program runs, it produces the output:
DemoEXTERNAL: **********
A subroutine mayCALLitself, either directly or indirectly from another subroutine or user-defined function that itCALL. Any subroutine that indulges in this sort of behaviour (called recursion) is called a ’Recursive Subprogram’
Any GnuCOBOL subroutine can be recursively invoked only if it is defined to the GnuCOBOL compiler as being a recursive subroutine. This is accomplished by adding theRECURSIVEattribute to it’sPROGRAM-ID(see IDENTIFICATION DIVISION).
All User-defined functions are automatically capable of being executed recursively.
Here is an example of a main program (DEMOFACT) that calls both a subprogram (SUB) and a user-defined function (FUNC) to compute the factorial value of a number.
IDENTIFICATION DIVISION.
PROGRAM-ID. DEMOFACT.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
FUNCTION RECURSIVEFUNC.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Result USAGE BINARY-LONG.
01 Arg USAGE BINARY-LONG.
PROCEDURE DIVISION.
000-Main.
MOVE 6 TO Arg
CALL "RECURSIVESUB"
USING BY CONTENT Arg
RETURNING Result
DISPLAY Arg "! = "
Result
DISPLAY Arg "! = "
RECURSIVEFUNC(Arg)
GOBACK
.
END PROGRAM DEMOFACT.
IDENTIFICATION DIVISION.
PROGRAM-ID. SUB RECURSIVE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Result USAGE BINARY-LONG.
01 Next-Arg USAGE BINARY-LONG.
01 Next-Result USAGE BINARY-LONG.
LINKAGE SECTION.
01 Arg USAGE BINARY-LONG.
PROCEDURE DIVISION USING Arg
RETURNING Result.
000-Main.
DISPLAY "Entering SUB"
" Arg=" Arg
IF Arg = 1
MOVE 1 TO Result
DISPLAY "Leaving SUB"
" Returning " Result
ELSE
SUBTRACT 1 FROM Arg
GIVING Next-Arg
CALL "SUB"
USING BY CONTENT Next-Arg
RETURNING Next-Result
COMPUTE Result =
Arg * Next-Result
DISPLAY "Leaving SUB"
" Returning "
Result "=" Arg "*"
Next-Result
END-IF
GOBACK
.
END PROGRAM SUB.
IDENTIFICATION DIVISION.
FUNCTION-ID. FUNC.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
FUNCTION RECURSIVEFUNC.
DATA DIVISION.
WORKING-STORAGE SECTION.
LINKAGE SECTION.
01 Arg USAGE BINARY-LONG.
01 Result USAGE BINARY-LONG
SIGNED.
PROCEDURE DIVISION USING Arg
RETURNING Result.
000-Main.
DISPLAY "Entering FUNC"
" Arg=" Arg
IF Arg = 1
MOVE 1 TO Result
ELSE
COMPUTE Result = Arg *
FUNC(Arg - 1)
END-IF
DISPLAY "Leaving FUNC"
" Returning " Result
GOBACK
.
END FUNCTION FUNC.
When DEMOFACT is executed, the output shown below is generated.
E:\Programs\Demos>demofact Entering RECURSIVESUB Arg=+0000000006 Entering RECURSIVESUB Arg=+0000000005 Entering RECURSIVESUB Arg=+0000000004 Entering RECURSIVESUB Arg=+0000000003 Entering RECURSIVESUB Arg=+0000000002 Entering RECURSIVESUB Arg=+0000000001 Leaving RECURSIVESUB Returning +0000000001 Leaving RECURSIVESUB Returning +0000000002=+0000000002*+0000000001 Leaving RECURSIVESUB Returning +0000000006=+0000000003*+0000000002 Leaving RECURSIVESUB Returning +0000000024=+0000000004*+0000000006 Leaving RECURSIVESUB Returning +0000000120=+0000000005*+0000000024 Leaving RECURSIVESUB Returning +0000000720=+0000000006*+0000000120 +0000000006! = +0000000720 Entering RECURSIVEFUNC Arg=+0000000006 Entering RECURSIVEFUNC Arg=+0000000005 Entering RECURSIVEFUNC Arg=+0000000004 Entering RECURSIVEFUNC Arg=+0000000003 Entering RECURSIVEFUNC Arg=+0000000002 Entering RECURSIVEFUNC Arg=+0000000001 Leaving RECURSIVEFUNC Returning +0000000001 Leaving RECURSIVEFUNC Returning +0000000002 Leaving RECURSIVEFUNC Returning +0000000006 Leaving RECURSIVEFUNC Returning +0000000024 Leaving RECURSIVEFUNC Returning +0000000120 Leaving RECURSIVEFUNC Returning +0000000720 +0000000006! = +0000000720
The upcoming sections deal the issues pertaining to calling C language programs from GnuCOBOL programs, and vice versa. Two additional sections provide samples illustrating specifics as to how those issues are overcome in actual program code.
Like most other implementations of the COBOL language, GnuCOBOL utilizes a run-time library. When the first program executed in a given execution sequence is a GnuCOBOL program, any run-time library initialization will be performed by the compiled COBOL code in a manner that is transparent to the C-language programmer. If, however, a C program is the first to execute, the burden of performing GnuCOBOL run-time library initialization falls upon the C program. See C Main Programs Calling GnuCOBOL Subprograms, for an example of how to do this.
Both languages store strings as a fixed-length continuous sequence of characters.
COBOL stores these character sequences up to a specific quantity limit imposed by thePICTURE(see PICTURE) clause of the data item. For example:01 LastName PIC X(15).
There is never an issue of exactly what the length of a string contained in aUSAGE DISPLAY(see USAGE) data item is — there are always exactly how ever many characters as were allowed for by thePICTUREclause. In the example above, "LastName" will always contain exactly fifteen characters; of course, there may be anywhere from 0 to 15 trailing SPACES as part of the current LastName value.
C actually has no "string" data type; it stores strings as an array ofchardata type items where each element of the array is a single character. Being an array, there is an upper limit to how many characters may be stored in a given "string". For example:
char lastName[15]; /* 15 chars: lastName[0] through lastName[14] */ C provides a robust set of string-manipulation functions to copy strings from one char array to another, search strings for certain characters, compare one char array to another, concatenate char arrays and so forth. To make these functions possible, it was necessary to be able to define the logical end of a string. C accomplishes this via the expectation that all strings (char arrays) will be terminated by a NULL character (x’00’). Of course, no one forces a programmer to do this, but if [s]he ever expects to use any of the C standard functions to manipulate that string they had better be null-terminating their strings!
So, GnuCOBOL programmers expecting to pass strings to or receive strings from C programs had best be prepared to deal with the null-termination issue, as follows:
01 LastName-Arg-to-C PIC X(16).
...
MOVE FUNCTION CONCATENATE(LastName,X'00') TO LastName-Arg-to-C
And then pass LastName-Arg-to-C to the C subprogram!
INSPECTstatement (see INSPECT) such as the following: INSPECT Data-From-a-C-Program
REPLACING FIRST X'00' BY SPACE
CHARACTERS BY SPACE AFTER INITIAL X'00'
Matching up GnuCOBOL numeric Usage s with their C language data type equivalents is possible via the following chart:
| COBOL | C |
|---|---|
| BINARY-CHAR [ UNSIGNED ] | unsigned char |
| BINARY-CHAR SIGNED | signed char |
| BINARY-SHORT [ UNSIGNED ] | unsigned unsigned int unsigned short unsigned short int |
| BINARY-CHAR [ UNSIGNED ] | unsigned char |
| BINARY-CHAR SIGNED | signed char |
| BINARY-SHORT [ UNSIGNED ] | unsigned unsigned int unsigned short unsigned short int |
| BINARY-SHORT SIGNED | int short short int signed int signed short signed short int |
| BINARY-LONG [ UNSIGNED ] | unsigned long unsigned long int |
| BINARY-LONG SIGNED BINARY-INT | long long int signed long signed long int |
| BINARY-C-LONG SIGNED | long |
| BINARY-DOUBLE [ UNSIGNED ] | unsigned long long unsigned long long int |
| BINARY-DOUBLE SIGNED BINARY-LONG-LONG | long long int signed long long int |
| COMPUTATIONAL-1 | float |
| COMPUTATIONAL-2 | double |
| N/A (no GnuCOBOL equivalent) | long double |
These are the ANSI2002 standard specifications for C-program data compatibility and GnuCOBOL programmers should get used to using them when data is being shared with C programs (they’re good documentation too, highlighting the fact that the data will be "shared" with a C program).
Here’s a sample of a GnuCOBOL program that CALLs a C subprogram.
COBOL Calling Program C Called Program
================================== ===============================
IDENTIFICATION DIVISION. #include <stdio.h>
PROGRAM-ID. maincob. int subc(char *arg1,
DATA DIVISION. char *arg2,
WORKING-STORAGE SECTION. unsigned long *arg3) {
01 Arg1 PIC X(7). char nu1[7]="New1";
01 Arg2 PIC X(7). char nu2[7]="New2";
01 Arg3 USAGE BINARY-LONG. printf("Starting subc\n");
PROCEDURE DIVISION. printf("Arg1=%s\n",arg1);
000-Main. printf("Arg2=%s\n",arg2);
DISPLAY 'Starting maincob' printf("Arg3=%d\n",*arg3);
MOVE Z'Arg1' TO Arg1 arg1[0]='X';
MOVE Z'Arg2' TO Arg2 arg2[0]='Y';
MOVE 123456789 TO Arg3 *arg3=987654321;
CALL 'subc' return 2;
USING BY CONTENT Arg1, }
BY REFERENCE Arg2,
BY REFERENCE Arg3
DISPLAY 'Back'
DISPLAY 'Arg1=' Arg1
DISPLAY 'Arg2=' Arg2
DISPLAY 'Arg3=' Arg3
DISPLAY 'Returned value='
RETURN-CODE
STOP RUN
.
The idea is to pass two string and one full-word unsigned arguments to the subprogram, have the subprogram print them out, change all three and pass a return code of 2 back to the caller. The caller will then re-display the three arguments (showing changes only to the twoBY REFERENCEarguments), display the return code and halt.
While simple, these two programs illustrate the techniques required quite nicely.
Note how the COBOL program ensures that a null end-of-string terminator is present on both string arguments.
Since the C program is planning on making changes to all three arguments, it declares all three as pointers in the function header and references the third argument as a pointer in the function body. It actually had no choice for the two string (char array) arguments – they must be defined as pointers in the function even though the function code references them without the leading * that normally signifies pointers.
These programs are compiled and executed as follows.
$ cobc -x maincob.cbl subc.c $ maincob Starting maincob Starting subc Arg1=Arg1 Arg2=Arg2 Arg3=123456789 Back Arg1=Arg1 Arg2=Yrg2 Arg3=+0987654321 Returned value=+000000002 $
Remember that the null characters are actually in the GnuCOBOL "Arg1" and "Arg2" data items. They don’t appear in the output, but they ARE there.
Did you notice the output showing the contents of "Arg1" after the subroutine was called? Those contents were unchanged! The subroutine definitely changed that argument, but since the COBOL program passed that argumentBY CONTENT the change was made to a copy of the argument, not to the "Arg1" data item itself.
Now, the roles of the two languages in the previous section will be reversed, having a C main program execute a GnuCOBOL subprogram.
C Calling Program GNU-COBOL Called Program
============================================= =================================
#include <libcob.h> /* COB RUN-TIME */ IDENTIFICATION DIVISION.
#include <stdio.h> PROGRAM-ID. subcob.
int main (int argc, char **argv) { DATA DIVISION.
int returnCode; LINKAGE SECTION.
char arg1[7] = "Arg1"; 01 Arg1 PIC X(7).
char arg2[7] = "Arg2"; 01 Arg2 PIC X(7).
unsigned long arg3 = 123456789; 01 Arg3 USAGE BINARY-LONG.
printf("Starting mainc...\n"); PROCEDURE DIVISION USING
cob_init (argc, argv); /* COB RUN-TIME */ BY VALUE Arg1,
returnCode = subcob(arg1,arg2,&arg3); BY REFERENCE Arg2,
printf("Back\n"); BY REFERENCE Arg3.
printf("Arg1=%s\n",arg1); 000-Main.
printf("Arg2=%s\n",arg2); DISPLAY 'Starting cobsub.cbl'
printf("Arg3=%d\n",arg3); DISPLAY 'Arg1=' Arg1
printf("Returned value=%d\n",returnCode); DISPLAY 'Arg2=' Arg2
return returnCode; DISPLAY 'Arg3=' Arg3
} MOVE 'X' TO Arg1 (1:1)
MOVE 'Y' TO Arg2 (1:1)
MOVE 987654321 TO Arg3
MOVE 2 TO RETURN-CODE
GOBACK
.
Since the C program is the one that will execute first, before the GnuCOBOL subroutine, the burden of initializing the GnuCOBOL run-time environment lies with that C program; it will have to invoke the "cob_init" function, which is part of the "libcob" library. The two required C statements are shown highlighted.
The arguments to the "cob_init" routine are the argument count and value parameters passed to the main function when the program began execution. By passing them into the GnuCOBOL subprogram, it will be possible for that GnuCOBOL program to retrieve the command line or individual command-line arguments. If that won’t be necessary, "cob_init(0,NULL);" could be specified instead.
Since the C program wants to allow "arg3" to be changed by the subprogram, it prefixes it with a "&" to force a CALL BY REFERENCE for that argument. Since "arg1" and "arg2" are strings (char arrays), they are automatically passed by reference.
Here’s the output of the compilation process as well as the program’s execution. The example assumes a Windows system with a GnuCOBOL build that uses the GNU C compiler on that system; the technique works equally well regardless of which C compiler and which operating system you’re using.
C:\Users\Gary\Documents\Programs> cobc -S subcob.cbl C:\Users\Gary\Documents\Programs> gcc mainc.c subcob.s -o mainc.exe -llibcob C:\Users\Gary\Documents\Programs> mainc.exe Starting mainc... Starting cobsub.cbl Arg1=Arg1 Arg2=Arg2 Arg3=+0123456789 Back Arg1=Xrg1 Arg2=Yrg2 Arg3=987654321 Returned value=2 C:\Users\Gary\Documents\Programs>
Note that even though we told GnuCOBOL that the 1st argument was to beBY VALUE it was treated as if it wereBY REFERENCEanyway. String (char array) arguments passed from C callers to GnuCOBOL subprograms will be modifiable by the subprogram. It’s best to pass a copy of such data if you want to ensure that the subprogram doesn’t change it.
The third argument is different, however. Since it’s not an array you have the choice of passing it eitherBY REFERENCEorBY VALUE
There’s no particular order of importance to the topics presented here.
Historically in the early 60’s programs were first punched on to paper tape and by the mid 60’s that was replaced almost totally, by punched cards although paper tape was still used by programmers for the odd few changes to their sources held on magnetic tape or disk as a portable paper tape punch could be put in your pocket. Now the problem with punched cards were there was 2,000 cards per box and that they could and did, get dropped. So, cc (column) 1 through 6 had the card sequence number in and that way if a box was dropped they could be feed in to a card sorter to be fixed. This was after the cards was cleaned up so that they were all in the same direction which one corner cut out helped.
In the late 70’s cards was also on its way out to the point where P.C’s started being used (and no they were not made by IBM), so these columns could be used for other purposes including cc 73 - 80 instead of indicating the 8 character program name which was the maximum size allowed on a IBM system.
For quite a while now (back to the late 1970’s), the "sequence number area" of a COBOL statement (columns 1-6) has come to be used as a change indicator area. Programmers would place a code in columns 1-6 of every line they changed in a program. The author works in a COBOL shop where change indicators of the form "xxmmyy" are required on every altered line of a program — "xx" is the initials of the programmer while "mmyy" are the month and two-digit year of the date the change was made. This is frequently accompanied by a comment block at or near the top of a COBOL program providing general documentation of what changes were made and what change indicator was used to mark that change.
The GCic sample program source listing (see GCic in GnuCOBOL Sample Programs) provides an excellent example of such documentation.
This technique of using columns 1-6 as a change indicator will ONLY work if fixed source-record format is in effect.
Some COBOL shops prefer to use the eight-character Program Name Area (columns 73-80) as a change code area.
Marking changes becomes more of a challenge when free-format source code is in effect. Creating a top-of-program comment block to generically describe changes that have been made isn’t difficult, even in free-form. What IS difficult, however, is coming up with a scheme for per-statement mark up of changes that doesn’t introduce a ridiculously excessive number of source lines to the program. I’m not sure there is a good answer to this problem (if a reader has one, please let me know). Generally, I’ve noticed that shops using free-format conventions for their COBOL source tend to stick with just the top-of-program comment block combined with minimal comment blocks sprinkled throughout the program noting areas that underwent major changes.
When programs get very large, it becomes more and more challenging to keep track of the data items that will be used in the program. Here, in no particular order of importance, are a variety of conventions that can simply that problem.
Remember that the points described here are intended to make things easier for you, the programmer. No COBOL compiler cares one way or another whether any of these suggestions are followed.
A convention such as this makes it simple, when you’re reviewing code in the procedure division, to know in which section of the data division you should look in when locating the detailed description of a data item. Once you’re in the right division, coding convention #2 will assist in locating the data item definition.
The data item contains all or a part of an Address (City-ADDR, State-ADDR, Street-ADDR, …)
A level-88 data item (which only has the value TRUE or FALSE)
A CODE whose value denotes information content above and beyond that of the mere value itself. Some examples could be "Error-CD", "Status-CD", "Billing-CD"
A data item containing a single character of data.
A constant, specified as a level-78 data item, a level-01 item with the CONST attribute
The data item contains a complete or partial date (Birth-DT, Birth-Month-DT, Birth-Year-DT, …)
A data item containing both a date and a time
A file name. Note that these items would probably also have a "F-" prefix.
A data item used as a table index (see section 10.3)
All or a portion of a person’s name. These could be extended to include business names, product names, etc.
A data item whose USAGE is POINTER
A generic numeric data item that doesn’t fit into any of the other categories
A count of something
An 01-level item defined in the FILE SECTION (constituting the layout of a record within a file). Note that these items would probably also have a "F-" prefix.
The data item contains a complete or partial screen description (appropriate for SCREEN SECTION 01-level data items).
A numeric item used as a table subscript (see section 10.3)
All or part of a telephone number
The data item contains a complete or partial time value
The data item contains generic alphanumeric text that doesn’t fit into any of the other categories.
The above is by no means an exhaustive list, but good programmers will use as few of these descriptors as possible as having too many defeats any benefits of such classification/documentation efforts.
01 WS-File-Status-Message-TXT.
05 FILLER PIC X(13) VALUE 'Status Code: '.
05 WS-FSM-Status-CD PIC 9(2).
05 FILLER PIC X(11) VALUE ', Meaning: '.
05 WS-FSM-Msg-TXT PIC X(25).
The "-FSM-" acronyms make it easier to locate the description of the 01-item the status code and message text items belong to.
The elements of a table may be referenced either using a subscript or an index. Syntactically, this is coded using parenthesis, as per the following three examples, all of which store the letter "A" into the 17th occurrence of a data item named WSS-Output-Image-TXT:
MOVE 'A' TO WSS-Output-Image-TXT (17) MOVE 17 TO WSS-OI-SUB MOVE 'A' TO WSS-Output-Image-TXT (WSS-OI-SUB) SET WSS-OI-IDX TO 17 MOVE 'A' TO WSS-Output-Image-TXT (WSS-OI-IDX) The 1st and 2nd examples are referred to as ’Subscripting’
Indexing is the process of referencing an element of a table utilizing a data item with an explicitly or implicitly definedUSAGE(see USAGE) ofINDEXto select the desired occurrence, while …
Subscripting is the process of referencing an element of a table utilizing either a numeric constant or an unedited numeric data item to select the desired occurrence.
Various implementations of COBOL generate object code that is quite different in each of these three situations, and GnuCOBOL is no exception.
In general, table references such as example #1 (constant subscript) generate the smallest, simplest and fastest object code while table references such as example #2 (numeric data item subscript) generate the largest, most-complicated and slowest object code.
Table references such as example #3 (table indexing) generate object code that falls in the middle of the other two but is far closer in efficiency to example #1 than #2.
Some COBOL statements SEARCH(see SEARCH),SEARCH ALL(see SEARCH ALL) and the table-basedSORT(see Table SORT)) require you to index the affected table and to utilize that index with those statements. With any other references to tables, the choice is left to the programmer as to which approach should be used. In general, follow these rules:
It’s impossible to perform any arithmetic operation against an index data item directly (other than a simple incrementation or decremental operation via theSET UP/DOWNstatement (see SET UP/DOWN)). Situations where any non-trivial computations are required to calculate the effective occurrence number for a table reference will require you to use a conventional unedited numeric data item as the receiving field for the calculation. That calculated value would then need to be saved into the index data item via aSET Indexstatement.
If you only need to use the computed occurrence number once, you might as well just use the computed occurrence number data item as a subscript. If, however, you will need to use a computed "subscript" many more times than once, the run-time overhead of converting that occurrence value to an index (viaSET Index will be worth the coding effort.
Whew!
If references to table elements are not going to be performed many, many times it probably won’t make much difference whether you use indexing or subscripting.
If you are comfortable with the "C" programming language, you might find the following simple GnuCOBOL program useful in exploring the differences between subscripting and indexing:
IDENTIFICATION DIVISION.
PROGRAM-ID. SUBVSINDEX.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-TABLE-SUB BINARY-LONG.
01 WS-TABLE.
05 WS-TABLE-ENTRY OCCURS 20 TIMES
INDEXED BY WS-TABLE-IDX
PIC X(1).
PROCEDURE DIVISION.
000-Main SECTION.
E1. MOVE 'A' TO WS-TABLE-ENTRY (17)
.
E2. MOVE 17 TO WS-TABLE-SUB
MOVE 'A' TO WS-TABLE-ENTRY (WS-TABLE-SUB)
.
E3. SET WS-TABLE-IDX TO 17
MOVE 'A' TO WS-TABLE-ENTRY (WS-TABLE-SUB)
.
Compile this program as follows (the assumption is made that you are executing thecobccommand from the directory in which the above program source code (subvsindex.cbl) exists.
cobc -C -save-temps subvsindex.cbl After this command is executed, the file "subvsindex.c" will contain the procedure division C code and "subvsindex.c.1.h" will contain the working-storage C code. Compare the generated C code for each of the threeMOVEstatements.
Since the intent of a copybook is to introduce COBOL code into a particular spot in a program via theCOPYstatement (see COPY), it is always a good idea to prefix copybook names with a character sequence that identifies where in a program it’s contents are intended to be copyed.
For example:
IDxxxxxxxxCopybooks containing code intended for the identification division. These will be rare as you almost never encounter copied code in the identification division.
EDxxxxxxxxCopybooks containing code intended for use in the environment division. These copybooks are generally used for predefinedSPECIAL-NAMES(see SPECIAL-NAMES) orFILE-CONTROL(see INPUT-OUTPUT SECTION) syntax,
DDxxxxxxxxCopybooks that contain data definitions.
PDxxxxxxxxCopybooks that contain executable instructions.
The issue of whether to use section and/or paragraph names (collectively referred to as procedure names) within the procedure division is one of near religious significance with many COBOL programmers.
COBOL programming standards used by many organizations that use the language generally call for procedure names to:
2000-Update-Customer, AND… When you are looking at or editing any large COBOL program that has been created with programming standards that include these two rules, it is always a simple thing to know whether a reference to a procedure is being made to code that exists before or after your current location in the program, simply by comparing the numeric component of the current procedure’s name with the one in question.
Technically, GnuCOBOL does not require ANY procedure names be defined unless:
ALTERstatement (see ALTER) (the use of which should be avoided at all costs) PERFORMstatement (see Procedural PERFORM) GO TOstatement (see GO TO) MERGEstatement (see MERGE) with anOUTPUT PROCEDURE
SORTstatement (see SORT) with either (or both) anINPUT PROCEDUREorOUTPUT PROCEDURE
DECLARATIVES(see DECLARATIVES) Since it is difficult to write any non-trivial COBOL program that uses none of the above, lets assume you will be including at least one section or paragraph in your GnuCOBOL programs.
I like to use procedure division paragraphs and sections as follows:
DECLARATIVES(see DECLARATIVES) are defined, will be a section named "000-Main". The declaration of this procedure will immediately follow the procedure division header (orEND DECLARATIVESifDECLARATIVESare used). MERGEPERFORM orSORTstatements will be defined as sections. GO TOstatements will be defined as paragraphs, and those paragraphs will be defined in the same section as theGO TOstatements that reference them. In other words,GO TOstatements may not be used to transfer control to a point in a different section. This is NOT a GnuCOBOL rule — this is my own personal programming practice intended to improve the readability and maintainability of my programs. THRUon anyMERGEPERFORMorSORTstatement unless the programming standards of the shop in which I am working require it. My reasoning for this is that it is too easy to accidentally introduce a new procedure into the scope of aTHRU Over the years, there has been much debate over the efficiency and arithmetic accuracy of using theCOMPUTEstatement (see COMPUTE) rather than the four basic arithmetic operation statements.
Here are the facts — draw your own conclusions as to which approach is more appropriate under which circumstances.
COMPUTEstatement supports exponentiation (via the "**" operator) — there is no equivalent basic arithmetic statement. Although you could simulate integral exponentiation (raising a value to the third power, for example) usingMULTIPLYstatements, and you may use theSQRTintrinsic function (see SQRT) to find a square root, there’s just no (easy) way to find the cube-root of a value without using theCOMPUTEstatement. COMPUTEstatements "read" better. Take this, for example: COMPUTE R = (A + B * C) / D
As compared to:
MULTIPLY B BY C GIVING TEMP ADD A TO TEMP DIVIDE TEMP BY D GIVING R
For non-trivial computations,COMPUTEstatements may execute faster than the equivalent chain of basic arithmetic statements. For example, the COMPUTE statement shown above executes about 25% faster on my computer using GnuCOBOL than does the MULTIPLY-ADD-DIVIDE sequence.
ADD 1 TO WSS-Input-Trans-QTY
to this:
COMPUTE WS-Input-Trans-QTY = WS-Input-Trans-QTY + 1
A data item whosePICTUREclause allows it to contain only upper- and/or lower-case letters. See PICTURE.
A data item whosePICTUREclause allows it to contain absolutely any character whatsoever. See PICTURE. Group items (see Structured Data) are also implicitly considered to be alphanumeric data items.
A string of characters enclosed within a pair of quotation marks (") or apostrophes (’). See Alphanumeric Literals.
Another way to refer to a subprogram. Note that a called program may also be a calling program.
A program that executes a subprogram. Note that a calling program may also be a called program.
The sequence in which the characters that are acceptable to a computer are ordered for purposes of all types of sorting, merging, comparing, and processing. GnuCOBOL programs may utilize standard character-set collating sequences (such as that defined by the ASCII or EBCDIC character sets) or programmer-defined custom sequences as specified in the OBJECT-COMPUTER paragraph (section 4.1.2) and defined in the SPECIAL-NAMES paragraph (section 4.1.4).
The collection of all compilation units being compiled by a single execution of the GnuCOBOL compiler.
A single source file being compiled by the GnuCOBOL compiler. A compilation unit may contain one or more programs.
An event that is triggered when a control field on an RWCS-generated report changes value. It is these events that trigger the generation of control heading and control footing groups.
A field of data being presented within a detail group; as the various detail groups that comprise the report are presented, they are presumed to appear in sorted sequence of the control fields contained within them. As an example, a department-by-department sales report for a chain of stores would probably be sorted by store number and – within like store numbers – be further sorted by department number. The store number will undoubtedly serve as a control field for the report, allowing control heading groups to be presented before each sequence of detail groups for the same store and control footing groups to be presented after each such sequence.
A report group that appears immediately after one or more detail groups of an RWCS-generated report. Such are produced automatically as a result of a control break. This type of group typically serves as a summary of the detail group(s) that precede it, as might be the case on a sales report for a chain of stores, where the detail groups documenting sales for each department (one department per detail group) from the same store might be followed by a control footing that provides a summation of the department-by-department sales for that store.
A report group that appears immediately before one or more detail groups of an RWCS-generated report. Such are produced automatically as a result of a control break. This type of group typically serves as an introduction to the detail group(s) that follow, as might be the case on a sales report for a chain of stores, where the detail groups documenting sales for each department (one department per detail group) from the same store might be preceded by a control heading that states the full name and location of the store.
The natural hierarchy of control breaks within a RWCS-controlled report based upon the manner in which the data the report is being generated from is sorted.
A segment of program code that may be utilized by multiple programs simply by having that program use the COPY statement to import that code into the program. Although similar to the "include" facility present in many other programming languages, the COBOL copybook mechanism is actually considerably more powerful. See Copybooks, for a general discussion. See COPY, for the specifics of the COPY statement.
A contiguous area of storage within the memory space of a program that may be referenced, by name, in a COBOL program. Other programming languages use the term variable, property or attribute to describe the same concept. See Structured Data.
A report group that contains the detailed data being presented for the report.
An RWCS-generated report to which at least one type of detail group is presented.
A collection of zero, one, or more sections of paragraphs, called the division body, that are formed and combined in accordance with a specific set of rules. Each division consists of the division header and the related division body. There are four divisions in a GnuCOBOL program: Identification, Environment, Data, and Procedure (coded in that sequence). See Program Structure.
A subprogram whose executable object code is contained in a different executable file as its calling program. Dynamic subprograms are therefore loaded into memory as needed.
A data item that isn’t itself comprised of other data items. See Structured Data.
A spot in the procedure division where a program may begin execution when it is executed from the operating system, invoked as a user-defined function or called by another program.
Every program has at least one entry-point — known as the primary entry-point — which corresponds to the first executable statement in the procedure division following the declaratives area, if any.
Additional entry-points may be defined via theENTRYstatement (see ENTRY).
Every entry-point has a name. That name must be unique for all programs that comprise an executable program. Entry-point names are defined using a subroutine’sPROGRAM-IDparagraph, a user-defined function’sFUNCTION-IDparagraph or viaENTRY(see ENTRY) statements coded in a subprogram’s procedure division.
The GnuCOBOL compiler can create operating-system appropriate files that may be executed directly from the operating system environment. On Windows systems, these will be ".exe" files whereas on UNIX systems they will have no specific extensions. The compiler’s-xswitch
The complete set of executable code that is run during the execution of a program. This includes the main program as well as all executed subprograms, including those that are both dynamically and statically loaded.
GnuCOBOL, like other COBOL implementations, supports a number of reserved words that may be used to represent a specific literal value. These are known as figurative constants. See Figurative Constants, for more information.
A mode of the GnuCOBOL compiler’s operation where source statements are constrained to meeting the pre-2002 standard of limiting COBOL statements to 80 columns, with various columns having limitations as to what sort of COBOL syntax could be specified in them. See Format of Program Source Lines, for more information.
A mode of the GnuCOBOL compiler’s operation where source statements are allowed to be as long as 255 characters, with no restrictions or requirements as to in which columns various syntax elements must appear. See Format of Program Source Lines, for more information.
A hierarchical data structure where the group item — itself a data item — actually consists of two or more other contiguously allocated data items. For example, ’Employee-Name’ could be a 35-character data item consisting of a 20-character ’Last-Name’ data item followed by a 14-character ’First-Name’ and a 1-character ’Middle-Initial’. See Structured Data.
These are alphanumeric literals whose character sequence is specified by hexadecimal value. These literals are formed by a quote- or apostrophe-delimited sequence of an even number of hexadecimal digits (upper- or lower-case), prefixed with the letter "X" (also upper- or lower-case). For example, the character string "Demo" could be specified as the hexadecimal alphanumeric literalX'44656D6F' assuming the ASCII character set. See Alphanumeric Literals.
A numeric literal whose value is specified by hexadecimal value. These literals are formed by a quote- or apostrophe-delimited sequence of from 1 to 16 hexadecimal digits (upper- or lower-case), prefixed with the letter "H" (also upper- or lower-case). For example, the number 123456 could be specified as the hexadecimal numeric literalH'01E240' See Numeric Literals.
These are data items a COBOL program will be working with. The vast majority of identifiers are defined by the user (programmer) while a few are pre-defined by the GnuCOBOL compiler. Identifiers pre-defined by the compiler are referred to as special registers. Other programming languages generally refer to identifiers as "variables".
Either a statement that begins with a non decision-making verb and specifies an unconditional action to be taken or a conditional verb such asIForEVALUATE delimited by its explicit scope terminator (such asEND-IForEND-EVALUATE. An imperative statement can consist of a sequence of imperative statements.
A built-in routine that accepts arguments and returns a value; syntactically, these may be used most places where GnuCOBOL identifiers are valid. See Intrinsic Functions, for documentation on all the GnuCOBOL intrinsic functions.
A 1- or 2-digit number that indicates the hierarchical position of a data item in a group item or the special properties of a data description entry.
Level numbers in the range 1 through 49 indicate the position of a data item in the hierarchical structure of a logical record. Level numbers in the range 1 through 9 can be written either as a single digit or as a zero followed by the significant digit.
Level numbers 66, 77, 78 and 88 identify special properties of a data description entry.
A generic term used for a constant value coded in a program that may be either a numeric literal or an alphanumeric literal.
A program that is executed directly from an operating system or shell event. Main programs are not executed from other programs (i.e. they are not called programs).
A character set that supports symbols using other than the traditional Roman alphabet symbols used by the ASCII character set. Typically, such a character set uses a UTF-16 (i.e. 16 bits-per-character) encoding of the Unicode character set.
Support for national character sets in GnuCOBOL is currently only partially implemented, and the compile- and run-time effect of using theNsymbol in aPICTURE(see PICTURE) clause to define a field as containing national characters is the same as ifX(2)had been coded, with the additional effect that such a field will qualify as aNATIONALorNATIONAL-EDITEDfield on anINITIALIZE(see INITIALIZE) statement.
A data item whosePICTUREclause allows it to contain only the numeric digit characters09(signed or unsigned), or a data item whosePICTUREUSAGEcombination allow it to contain actual binary numbers in integer, fixed-point, floating-point or packed-decimal format. Numeric data items are the only ones that may be used as table subscripts or as source arguments on arithmetic statements.PICTURE(see PICTURE), orUSAGE(see USAGE).
An otherwise numeric data item whosePICTURE(see PICTURE) clause also contains any of the editing symbols$*+,-./0(zero),BCRDBorZ Numeric edited data items are not eligible to serve as table subscripts or source arguments on arithmetic statements.
A numeric constant. See Numeric Literals.
A report group that appears at the bottom of every page of an RWCS-generated report. Information typically found within such a report group might be:
A report group that appears at the top of every page of an RWCS-generated report. Information typically found within such a report group might be:
See entry-point.
All executable code statements within a single procedure division paragraph or section.
A programmer-defined section or paragraph name in the procedure division assigned to a procedure. Procedure names serve as a means by which a statement may refer to the statements that follow the procedure name.
A GnuCOBOL main program or subprogram.
The process of establishing a unique reference to a data item whose name is duplicated in a program. This takes the form of using the duplicated data name and the name of any of its parent data items, connected byOForINsuch that the combination of those two data names is unique within the program.
A group item that is not part of a higher-level group item. See Data Definition Principles. An elementary item with a level number of 01 can also be referred to as a record if it’s definition occurs in the file section, provided that it’s definition does not include theCONSTANTattribute. See FILE-SECTION-Data-Item.
A report group that occurs only once in an RWCS-generated report — as the very last presented report group of the report. These typically serve as a visual indication that the report is finished.
One or more consecutive lines on a report that serve a common informational purpose or function. For example, lines of text that are displayed at the top or bottom of every printed page of a report.
A report group that occurs only once in an RWCS-generated report — as the very first presented report group of the report. These typically serve as an introduction to the report.
A word coded in a GnuCOBOL program without any quote or apostrophe characters around it (which would have transformed that sequence of characters into a literal string) which has a very specific meaning to the compiler. See Language Reserved Words, for a general discussion of the concept. See Appendix B - Reserved Word List, for a complete list of GnuCOBOL reserved words.
An arbitrarily long sequence of statements terminated by a period.
Special data items that are automatically defined for your use by the GnuCOBOL compiler. See Special Registers, for a complete list.
A single executable COBOL instruction. All statements start with a verb DISPLAYIFMOVE ...) which is followed by the operands and additional syntax elements that describe the actions to be performed.
A subprogram whose executable object code is part of the same executable file as its calling program. Static subprograms are therefore loaded into memory at the same time as their caller.
A program invoked directly by another program in such a manner that it may return control back to the other program, directly back to the point where the subprogram was invoked.
A subprogram executed from another via a GnuCOBOLCALL(see CALL) statement (or the equivalent in whatever programming language that other program was written in).
An RWCS-generated report to which no detail groups are presented.
A subprogram written in GnuCOBOL that is executed in a syntactically-similar manner to that by which the various built-in intrinsic functions are executed.
Either the name of an identifier or a procedure in the program. GnuCOBOL limits user-defined names to a maximum of 31 characters taken from the set of numeric digits, upper- and lower-case letters, hyphens and underscores. A user-defined name may neither begin nor end with a hyphen or underscore. User-defined names used as file names may additionally not begin with a digit although - unlike many other programming languages - user-defined names used as identifiers or procedure names may.
The first reserved word of a COBOL statement.
An alphanumeric literal prefixed with an upper- or lower-case "Z" character — for example,Z'ABC' These literals are one character longer than the value within apostrophes or quotes would make them appear. The extra character (the last character) will be a null character (comprised entirely of zero bits). These literals are ideal when defining or assigning values to alphanumeric data items that will be passed as arguments to a C subroutine. See Alphanumeric Literals.
ABS, ACCEPT, ACCESS, ACOS, ACTIVE-CLASS, ADD, ADDRESS, ADVANCING, AFTER, ALIGNED, ALL, ALLOCATE, ALPHABET, ALPHABETIC, ALPHABETIC-LOWER, ALPHABETIC-UPPER, ALPHANUMERIC, ALPHANUMERIC-EDITED, ALSO, ALTER, ALTERNATE, AND, ANNUITY, ANY, ANYCASE, ARE, AREA, AREAS, ARGUMENT-NUMBER, ARGUMENT-VALUE, ARITHMETIC, AS, ASCENDING, ASCII, ASIN, ASSIGN, AT, ATAN, ATTRIBUTE, AUTHOR, AUTO, AUTOMATIC, AUTO-SKIP, AUTOTERMINATE, AWAY-FROM-ZERO
BACKGROUND-COLOR, BACKGROUND-COLOUR, B-AND, BASED, BEEP, BEFORE, BELL, BINARY, BINARY-CHAR, BINARY-C-LONG, BINARY-DOUBLE, BINARY-INT, BINARY-LONG, BINARY-LONG-LONG, BINARY-SHORT, BIT, BLANK, BLINK, BLOCK, B-NOT, BOOLEAN, BOOLEAN-OF-INTEGER, B-OR, BOTTOM, B-XOR, BY, BYTE-LENGTH
C01, C02, C03, C04, C05, C06, C07, C08, C09, C10, C11, C12, CALL, CALL-CONVENTION, CANCEL, CAPACITY, CD, CENTER, CF, CH, CHAIN, CHAINING, CHAR, CHAR-NATIONAL, CHARACTER, CHARACTERS, CLASS, CLASS-ID, CLASSIFICATION, CLOSE, COB-CRT-STATUS, CODE, CODE-SET, COL, COLLATING, COLS, COLUMN, COLUMNS, COMBINED-DATETIME, COMMA, COMMAND-LINE, COMMIT, COMMON, COMMUNICATION, COMP, COMP-1, COMP-2, COMP-3, COMP-4, COMP-5, COMP-6, COMP-X, COMPUTATIONAL, COMPUTATIONAL-1, COMPUTATIONAL-2, COMPUTATIONAL-3, COMPUTATIONAL-4, COMPUTATIONAL-5, COMPUTATIONAL-X, COMPUTE, CONCATENATE, CONDITION, CONFIGURATION, CONSOLE, CONSTANT, CONTAINS, CONTENT, CONTINUE, CONTROL, CONTROLS, CONVERSION, CONVERTING, COPY, CORR, CORRESPONDING, COS, COUNT, CRT, CRT-UNDER, CSP, CURRENCY, CURRENCY-SYMBOL, CURRENT-DATE, CURSOR, CYCLE
DATA, DATA-POINTER, DATE, DATE-COMPILED, DATE-MODIFIED, DATE-OF-INTEGER, DATE-TO-YYYYMMDD, DATE-WRITTEN, DAY, DAY-OF-INTEGER, DAY-OF-WEEK, DAY-TO-YYYYDDD, DE, DEBUGGING, DECIMAL-POINT, DECLARATIVES, DEFAULT, DELETE, DELIMITED, DELIMITER, DEPENDING, DESCENDING, DESTINATION, DETAIL, DISABLE, DISC, DISK, DISPLAY, DISPLAY-OF, DIVIDE, DIVISION, DOWN, DUPLICATES, DYNAMIC
E, EBCDIC, EC, ECHO, EGI, ELSE, EMI, EMPTY-CHECK, ENABLE, END, END-ACCEPT, END-ADD, END-CALL, END-CHAIN, END-COMPUTE, END-DELETE, END-DISPLAY, END-DIVIDE, END-EVALUATE, END-IF, END-MULTIPLY, END-OF-PAGE, END-PERFORM, END-READ, END-RECEIVE, END-RETURN, END-REWRITE, END-SEARCH, END-START, END-STRING, END-SUBTRACT, END-UNSTRING, END-WRITE, ENTRY, ENTRY-CONVENTION, ENVIRONMENT, ENVIRONMENT-NAME, ENVIRONMENT-VALUE, EO, EOL, EOP, EOS, EQUAL, EQUALS, ERASE, ERROR, ESCAPE, ESI, EVALUATE, EXCEPTION, EXCEPTION-FILE, EXCEPTION-FILE-N, EXCEPTION-LOCATION, EXCEPTION-LOCATION-N, EXCEPTION-OBJECT, EXCEPTION-STATEMENT, EXCEPTION-STATUS, EXCLUSIVE, EXIT, EXP, EXP10, EXPANDS, EXTEND, EXTERN, EXTERNAL
F, FACTORIAL, FACTORY, FALSE, FD, FILE, FILE-CONTROL, FILE-ID, FILLER, FINAL, FIRST, FIXED, FLOAT-BINARY-128, FLOAT-BINARY-32, FLOAT-BINARY-64, FLOAT-DECIMAL-16, FLOAT-DECIMAL-34, FLOAT-EXTENDED, FLOAT-INFINITY, FLOAT-LONG, FLOAT-NOT-A-NUMBER, FLOAT-SHORT, FOOTING, FOR, FOREGROUND-COLOR, FOREGROUND-COLOUR, FOREVER, FORMAT, FORMATTED-CURRENT-DATE, FORMATTED-DATE, FORMATTED-DATETIME, FORMATTED-TIME, FORMFEED, FRACTION-PART, FREE, FROM, FULL, FUNCTION, FUNCTION-ID, FUNCTION-POINTER
GENERATE, GET, GIVING, GLOBAL, GO, GOBACK, GREATER, GRID, GROUP, GROUP-USAGE
HEADING, HIGHEST-ALGEBRAIC, HIGHLIGHT, HIGH-VALUE, HIGH-VALUES
ID, IDENTIFICATION, IF, IGNORE, IGNORING, IMPLEMENTS, IN, INDEX, INDEXED, INDICATE, INHERITS, INITIAL, INITIALISE, INITIALISED, INITIALIZE, INITIALIZED, INITIATE, INPUT, INPUT-OUTPUT, INSPECT, INSTALLATION, INTEGER, INTEGER-OF-BOOLEAN, INTEGER-OF-DATE, INTEGER-OF-DAY, INTEGER-OF-FORMATTED-DATE, INTEGER-PART, INTERFACE, INTERFACE-ID, INTERMEDIATE, INTO, INTRINSIC, INVALID, INVOKE, I-O, I-O-CONTROL, IS
JUST, JUSTIFIED
KEPT, KEY, KEYBOARD
LABEL. LAST, LC_ALL, LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC, LC_TIME, LEADING, LEFT, LEFT-JUSTIFY, LEFTLINE, LENGTH, LENGTH-AN, LENGTH-CHECK, LESS, LIMIT, LIMITS, LINAGE, LINAGE-COUNTER, LINE, LINE-COUNTER, LINES, LINKAGE, LOCALE, LOCALE-COMPARE, LOCALE-DATE, LOCALE-TIME, LOCALE-TIME-FROM-SECONDS, LOCAL-STORAGE, LOCK, LOG, LOG10, LOWER, LOWER-CASE, LOWEST-ALGEBRAIC, LOWLIGHT, LOW-VALUE, LOW-VALUES
MAGNETIC-TAPE, MANUAL, MAX, MEAN, MEDIAN, MEMORY, MERGE, MESSAGE, METHOD, METHOD-ID, MIDRANGE, MIN, MINUS, MOD, MODE, MODULE-CALLER-ID, MODULE-DATE, MODULE-FORMATTED-DATE, MODULE-ID, MODULE-PATH, MODULES, MODULE-SOURCE, MODULE-TIME, MONETARY-DECIMAL-POINT, MONETARY-THOUSANDS-SEPARATOR, MOVE, MULTIPLE, MULTIPLY
NAME, NATIONAL, NATIONAL-EDITED, NATIONAL-OF, NATIVE, NEAREST-AWAY-FROM-ZERO, NEAREST-EVEN, NEAREST-TOWARD-ZERO, NEGATIVE, NESTED, NEXT, NO, NO-ECHO, NONE, NORMAL, NOT, NOTHING, NULL, NULLS, NUMBER, NUMBER-OF-CALL-PARAMETERS, NUMBERS, NUMERIC, NUMERIC-DECIMAL-POINT, NUMERIC-EDITED, NUMERIC-THOUSANDS-SEPARATOR, NUMVAL, NUMVAL-C, NUMVAL-F
OBJECT, OBJECT-COMPUTER, OBJECT-REFERENCE, OCCURS, OF, OFF, OMITTED, ON, ONLY, OPEN, OPTIONAL, OPTIONS, OR, ORD, ORDER, ORD-MAX, ORD-MIN, ORGANISATION, ORGANIZATION, OTHER, OUTPUT, OVERFLOW, OVERLINE, OVERRIDE
PACKED-DECIMAL, PADDING, PAGE, PAGE-COUNTER, PARAGRAPH, PERFORM, PF, PH, PI, PIC, PICTURE, PLUS, POINTER, POSITION, POSITIVE, PREFIXED, PRESENT, PRESENT-VALUE, PREVIOUS, PRINT, PRINTER, PRINTER-1, PRINTING, PROCEDURE, PROCEDURE-POINTER, PROCEDURES, PROCEED, PROGRAM, PROGRAM-ID, PROGRAM-POINTER, PROHIBITED, PROMPT, PROPERTY, PROTECTED, PROTOTYPE, PURGE
QUEUE, QUOTE, QUOTES
RAISE, RAISING, RANDOM, RANGE, RD, READ, RECEIVE, RECORD, RECORDING, RECORDS, RECURSIVE, REDEFINES, REEL, REFERENCE, REFERENCES, RELATION, RELATIVE, RELEASE, REM, REMAINDER, REMARKS, REMOVAL, RENAMES, REPLACE, REPLACING, REPORT, REPORTING, REPORTS, REPOSITORY, REQUIRED, RESERVE, RESET, RESUME, RETRY, RETURN, RETURN-CODE, RETURNING, REVERSE, REVERSED, REVERSE-VIDEO, REWIND, REWRITE, RF, RH, RIGHT, RIGHT-JUSTIFY, ROLLBACK, ROUNDED, ROUNDING, RUN
S, SAME, SCREEN, SCROLL, SD, SEARCH, SECONDS, SECONDS-FROM-FORMATTED-TIME, SECONDS-PAST-MIDNIGHT, SECTION, SECURE, SECURITY, SEGMENT, SEGMENT-LIMIT, SELECT, SELF, SEND, SENTENCE, SEPARATE, SEQUENCE, SEQUENTIAL, SET, SHARING, SIGN, SIGNED, SIGNED-INT, SIGNED-LONG, SIGNED-SHORT, SIN, SIZE, SORT, SORT-MERGE, SORT-RETURN, SOURCE, SOURCE-COMPUTER, SOURCES, SPACE, SPACE-FILL, SPACES, SPECIAL-NAMES, SQRT, STANDARD, STANDARD-1, STANDARD-2, STANDARD-BINARY, STANDARD-COMPARE, STANDARD-DECIMAL, STANDARD-DEVIATION, START, STATEMENT, STATIC, STATUS, STDCALL, STDERR, STDIN, STDOUT, STEP, STOP, STORED-CHAR-LENGTH, STRING, STRONG, SUB-QUEUE-1, SUB-QUEUE-2, SUB-QUEUE-3, SUBSTITUTE, SUBSTITUTE-CASE, SUBTRACT, SUM, SUPER, SUPPRESS, SW0, SW1, SW10, SW11, SW12, SW13, SW14, SW15, SW2, SW3, SW4, SW5, SW6, SW7, SW8, SW9, SWITCH 0, SWITCH-0, SWITCH 1, SWITCH-1, SWITCH 10, SWITCH-10, SWITCH 11, SWITCH-11, SWITCH 12, SWITCH-12, SWITCH 13, SWITCH-13, SWITCH 14, SWITCH-14, SWITCH 15, SWITCH-15, SWITCH 16, SWITCH-16, SWITCH 17, SWITCH-17, SWITCH 18, SWITCH-18, SWITCH 19, SWITCH-19, SWITCH 2, SWITCH-2, SWITCH 20, SWITCH-20, SWITCH 21, SWITCH-21, SWITCH 22, SWITCH-22, SWITCH 23, SWITCH-23, SWITCH 24, SWITCH-24, SWITCH 25, SWITCH-25, SWITCH 26, SWITCH-26, SWITCH-27, SWITCH-28, SWITCH-29, SWITCH 3, SWITCH-3, SWITCH-30, SWITCH-31, SWITCH-32, SWITCH-33, SWITCH-34, SWITCH-35, SWITCH-36, SWITCH 4, SWITCH-4, SWITCH 5, SWITCH-5, SWITCH 6, SWITCH-6, SWITCH 7, SWITCH-7, SWITCH 8, SWITCH-8, SWITCH 9, SWITCH-9, SWITCH A, SWITCH B, SWITCH C, SWITCH D, SWITCH E, SWITCH F, SWITCH G, SWITCH H, SWITCH I, SWITCH J, SWITCH K, SWITCH L, SWITCH M, SWITCH N, SWITCH O, SWITCH P, SWITCH Q, SWITCH R, SWITCH S, SWITCH T, SWITCH U, SWITCH V, SWITCH W, SWITCH X, SWITCH Y, SWITCH Z, SYMBOL, SYMBOLIC, SYNC, SYNCHRONISED, SYNCHRONIZED, SYSERR, SYSIN, SYSIPT, SYSLIST, SYSLST, SYSOUT, SYSTEM, SYSTEM-DEFAULT, SYSTEM-OFFSET
TABLE, TALLYING, TAN, TAPE, TERMINAL, TERMINATE, TEST, TEST-DATE-YYYYMMDD, TEST-DAY-YYYYDDD, TEST-FORMATTED-DATETIME, TEST-NUMVAL, TEST-NUMVAL-C, TEST-NUMVAL-F, TEXT, THAN, THEN, THROUGH, THRU, TIME, TIME-OUT, TIMEOUT, TIMES, TO, TOP, TOWARD-GREATER, TOWARD-LESSER, TRAILING, TRAILING-SIGN, TRANSFORM, TRIM, TRUE, TRUNCATION, TYPE, TYPEDEF
U, UCS-4, UNBOUNDED, UNDERLINE, UNIT, UNIVERSAL, UNLOCK, UNSIGNED, UNSIGNED-INT, UNSIGNED-LONG, UNSIGNED-SHORT, UNSTRING, UNTIL, UP, UPDATE, UPON, UPPER, UPPER-CASE, USAGE, USE, USER, USER-DEFAULT, USING, UTF-16, UTF-8
V, VALID, VALIDATE, VALIDATE-STATUS, VAL-STATUS, VALUE, VALUES, VARIABLE, VARIANCE, VARYING
WAIT, WHEN, WHEN-COMPILED, WITH, WORDS, WORKING-STORAGE, WRITE
X"91", X"E4", X"E5", X"F4", X"F5"
YEAR-TO-YYYY, YYYYDDD, YYYYMMDD
ZERO, ZERO-FILL, ZEROES, ZEROS
Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
Licensed under the GNU Free Documentation License.
https://open-cobol.sourceforge.io/HTML/gnucobpg.html