snaums.de - Tutorialhttps://www.snaums.de/2019-03-03T19:00:00+01:00Learning COBOL with Examples - Part 2: FILE I/O2019-03-03T19:00:00+01:002019-03-03T19:00:00+01:00snaumstag:www.snaums.de,2019-03-03:/informatik/learning-cobol-with-examples-02.html<p>The previous post in this series was about learning the basics of the COBOL programming language. Now I will cover a very important and essential part of COBOL - File Input / Output (I/O). I find it really interesting, as I haven't seen any other language which makes it that easy …</p><p>The previous post in this series was about learning the basics of the COBOL programming language. Now I will cover a very important and essential part of COBOL - File Input / Output (I/O). I find it really interesting, as I haven't seen any other language which makes it that easy to read files for lines and break them up basically automatically. I suspect, that this is the reason COBOL exists and that most of the business applications did that a lot. </p>
<p>Well nowadays there is basically everything for COBOL, you can write web-services in COBOL, query databases with SQL and do loads more, as we will see in future posts.</p>
<p>The thumbnail is takes from Wiktionary [<a href="https://de.wiktionary.org/wiki/Stechuhr">1</a>] by User Ludek [<a href="https://commons.wikimedia.org/wiki/User:Ludek">2</a>].</p>
<h2 id="file-io">File I/O</h2>
<p>In programming files are basically containers of input- or output-data. In Linux, or Unix-Systems for that matter, files can also be pipes or sockets, which can be used to communicate with other programs. In this post I will only discuss opening, reading, writing and closing known files, i.e. using system calls to find files, or list them, is not part of this post. </p>
<p>There are basically four operations you want to do on files. Opening a file tells the Operating System to find the file on the disk, and make it accessible from your application. Internally the so called file descriptor of that file is added to the list of file descriptors of your process. This file descriptor can be used in languages like C for syscalls such as <code>read</code>. Closing a file tells the OS, that we are finished, the written content can be flushed to the disk, and the operation with this file is done. </p>
<p>Reading and writing from and to the file does exactly that. A read gets some data from that file and makes it usable via memory regions or variables, whereas writing data takes your variables or a memory region and transfers it into the file, at the current location of the file pointer. However writing is most of the times not immediate, but deferred, i.e. the operation is put off, until more data is there to write to the disk. </p>
<h2 id="the-example-program">The example program</h2>
<p>Take this example program I wrote year ago. It is supposed to read a file containing my worked hours per day, reformats the data and calculates a sum of the worked hours. It is an extremely simple program, but still it is loads of text in COBOL. </p>
<div class="highlight"><pre><span class="code-line"><span></span><code><span class="kr">IDENTIFICATION</span><span class="w"> </span><span class="kr">DIVISION</span><span class="p">.</span></code></span>
<span class="code-line"><span class="kr">PROGRAM-ID</span><span class="p">.</span><span class="w"> </span><span class="nv">wrkhrs</span><span class="p">.</span></span>
<span class="code-line"></span>
<span class="code-line"><span class="kr">ENVIRONMENT</span><span class="w"> </span><span class="kr">DIVISION</span><span class="p">.</span></span>
<span class="code-line"><span class="kr">INPUT-OUTPUT</span><span class="w"> </span><span class="kr">SECTION</span><span class="p">.</span></span>
<span class="code-line"><span class="kr">FILE-CONTROL</span><span class="p">.</span></span>
<span class="code-line"><span class="kp">select</span><span class="w"> </span><span class="nv">hrs</span></span>
<span class="code-line"><span class="w"> </span><span class="kp">assign</span><span class="w"> </span><span class="kp">to </span><span class="s2">"hours.txt"</span></span>
<span class="code-line"><span class="w"> </span><span class="kp">organization</span><span class="w"> </span><span class="kp">is</span><span class="w"> </span><span class="kp">line</span><span class="w"> </span><span class="kp">sequential</span><span class="p">.</span></span>
<span class="code-line"></span>
<span class="code-line"><span class="kp">select</span><span class="w"> </span><span class="nv">hrs-out</span></span>
<span class="code-line"><span class="w"> </span><span class="kp">assign</span><span class="w"> </span><span class="kp">to </span><span class="s2">"hours.out"</span></span>
<span class="code-line"><span class="w"> </span><span class="kp">organization</span><span class="w"> </span><span class="kp">is</span><span class="w"> </span><span class="kp">line</span><span class="w"> </span><span class="kp">sequential</span><span class="p">.</span></span>
<span class="code-line"></span>
<span class="code-line"><span class="kr">DATA</span><span class="w"> </span><span class="kr">DIVISION</span><span class="p">.</span></span>
<span class="code-line"><span class="kr">FILE</span><span class="w"> </span><span class="kr">SECTION</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">fd</span><span class="w"> </span><span class="nv">hrs</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">01 </span><span class="nv">hrs-record</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">d</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">Z9</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="kp">FILLER</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">dayname</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">XX</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="kp">FILLER</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">hours</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">XX</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="kp">FILLER</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">6</span><span class="p">).</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">descr</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">50</span><span class="p">).</span></span>
<span class="code-line"></span>
<span class="code-line"><span class="w"> </span><span class="kr">fd</span><span class="w"> </span><span class="nv">hrs-out</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">01 </span><span class="nv">hrs-out-rec</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">dayname</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">XX</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">a</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">2</span><span class="p">).</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">d</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">XX</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">b</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">7</span><span class="p">).</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">hours</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">XX</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">c</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">15</span><span class="p">).</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">descr</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">50</span><span class="p">).</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">01 </span><span class="nv">total-rec</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">s</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">14</span><span class="p">).</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">total</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">3</span><span class="p">).</span></span>
<span class="code-line"></span>
<span class="code-line"><span class="kr">WORKING-STORAGE</span><span class="w"> </span><span class="kr">SECTION</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">01 </span><span class="nv">ls</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">d</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="mi">99</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">dayname</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">XX</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">hours</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="mi">99</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">descr</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">50</span><span class="p">).</span></span>
<span class="code-line"></span>
<span class="code-line"><span class="w"> </span><span class="mi">01 </span><span class="nv">nmbr</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="mi">9</span><span class="p">(</span><span class="mi">3</span><span class="p">).</span></span>
<span class="code-line"></span>
<span class="code-line"><span class="kr">PROCEDURE</span><span class="w"> </span><span class="kr">DIVISION</span><span class="p">.</span></span>
<span class="code-line"><span class="nv">bg</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">OPEN</span><span class="w"> </span><span class="kp">INPUT</span><span class="w"> </span><span class="nv">hrs</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">OPEN</span><span class="w"> </span><span class="kp">OUTPUT</span><span class="w"> </span><span class="nv">hrs-out</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">MOVE</span><span class="w"> </span><span class="no">zeroes</span><span class="w"> </span><span class="kp">TO</span><span class="w"> </span><span class="nv">nmbr</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">MOVE </span><span class="s2">", "</span><span class="w"> </span><span class="kp">TO</span><span class="w"> </span><span class="nv">a</span><span class="w"> </span><span class="kp">of</span><span class="w"> </span><span class="nv">hrs-out-rec</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">MOVE </span><span class="s2">" Sep.: "</span><span class="w"> </span><span class="kp">TO</span><span class="w"> </span><span class="nv">b</span><span class="w"> </span><span class="kp">of</span><span class="w"> </span><span class="nv">hrs-out-rec</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">MOVE </span><span class="s2">" hrs., Report: "</span><span class="w"> </span><span class="kp">TO</span><span class="w"> </span><span class="nv">c</span><span class="w"> </span><span class="kp">of</span><span class="w"> </span><span class="nv">hrs-out-rec</span><span class="p">.</span></span>
<span class="code-line"></span>
<span class="code-line"><span class="nv">reed</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">READ</span><span class="w"> </span><span class="nv">hrs</span><span class="w"> </span><span class="kp">RECORD</span><span class="w"> </span><span class="kp">AT</span><span class="w"> </span><span class="kr">END</span><span class="w"> </span><span class="kr">go</span><span class="w"> </span><span class="kp">to</span><span class="w"> </span><span class="nf">e</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">MOVE</span><span class="w"> </span><span class="kp">CORR</span><span class="w"> </span><span class="nv">hrs-record</span><span class="w"> </span><span class="kp">TO</span><span class="w"> </span><span class="nv">ls</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">ADD</span><span class="w"> </span><span class="nv">hours</span><span class="w"> </span><span class="kp">OF</span><span class="w"> </span><span class="nv">ls</span><span class="w"> </span><span class="kp">TO</span><span class="w"> </span><span class="nv">nmbr</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">MOVE</span><span class="w"> </span><span class="kp">CORR</span><span class="w"> </span><span class="nv">ls</span><span class="w"> </span><span class="kp">TO</span><span class="w"> </span><span class="nv">hrs-out-rec</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">WRITE</span><span class="w"> </span><span class="nv">hrs-out-rec</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">go</span><span class="w"> </span><span class="kp">to</span><span class="w"> </span><span class="nv">reed</span><span class="p">.</span></span>
<span class="code-line"></span>
<span class="code-line"><span class="nf">e</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">MOVE </span><span class="s2">" Hours total: "</span><span class="w"> </span><span class="kp">TO</span><span class="w"> </span><span class="nv">s</span><span class="w"> </span><span class="kp">OF</span><span class="w"> </span><span class="nv">total-rec</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">MOVE</span><span class="w"> </span><span class="nv">nmbr</span><span class="w"> </span><span class="kp">TO</span><span class="w"> </span><span class="nv">total</span><span class="w"> </span><span class="kp">OF</span><span class="w"> </span><span class="nv">total-rec</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">WRITE</span><span class="w"> </span><span class="nv">total-rec</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">CLOSE</span><span class="w"> </span><span class="nv">hrs-out</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">CLOSE</span><span class="w"> </span><span class="nv">hrs</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">STOP</span><span class="w"> </span><span class="kp">RUN</span><span class="p">.</span></span>
<span class="code-line"></span></pre></div>
<h3 id="environment-division">Environment Division</h3>
<p>The environment division contains the Input-Output Section, which in turns holds the file-control-paragraphs. Here the two files, one for writing, one for reading is declared. </p>
<div class="highlight"><pre><span class="code-line"><span></span><code><span class="kp">select</span><span class="w"> </span><span class="nv">hrs</span></code></span>
<span class="code-line"><span class="w"> </span><span class="kp">assign</span><span class="w"> </span><span class="kp">to </span><span class="s2">"hours.txt"</span></span>
<span class="code-line"><span class="w"> </span><span class="kp">organization</span><span class="w"> </span><span class="kp">is</span><span class="w"> </span><span class="kp">line</span><span class="w"> </span><span class="kp">sequential</span></span>
<span class="code-line"></span></pre></div>
<p>Here the name <code>hrs</code> is chosen, by which this file will be refered to in the remainder of the program. The name is assigned to the path <code>hours.txt</code> and it is organized as lines, i.e. every record is finished with a newline-symbol. This also tells COBOL, that the file is text-based and not a binary file. <code>sequential</code> identifies the access pattern, i.e. in what order the file is read or written to. Other valid access patterns would be <code>random</code> or <code>dynamic</code>.</p>
<p>Both files are handled identically here, as COBOL makes in this part of the program no difference of input- or output-files. </p>
<h3 id="data-division">Data Division</h3>
<p>The data division contains two sections: the file section and the working-storage section. You should already know the working-storage section if you read the previous post, that is. </p>
<h4 id="file-section">File Section</h4>
<p>In the file section, records are defined. This is in my eyes a special point of COBOL, as it lets you define data structures explicitely for working with files and I/O in particular. There are three data structures defined here.</p>
<div class="highlight"><pre><span class="code-line"><span></span><code><span class="kr">fd</span><span class="w"> </span><span class="nv">hrs</span><span class="p">.</span></code></span>
<span class="code-line"><span class="mi">01 </span><span class="nv">hrs-record</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">d</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">Z9</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="kp">FILLER</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">dayname</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">XX</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="kp">FILLER</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">hours</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">XX</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="kp">FILLER</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">6</span><span class="p">).</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">descr</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">50</span><span class="p">).</span></span>
<span class="code-line"></span></pre></div>
<p>The data structure <code>hrs-record</code> is defined for use with the file <code>hrs</code>. The definition of the variables and fields is identical to what it would be in the working-storage section. The keyword <code>FILLER</code> however is something special. It basically serves as a placeholder, as you want the Space in line 3 for example, but you don't you to access it every. So one can use the "name" <code>FILLER</code> to let the compiler know, that I will never access it and I don't want any name registered with this field of the record. This means I can use it more than once in my program.</p>
<div class="highlight"><pre><span class="code-line"><span></span><code><span class="kr">fd</span><span class="w"> </span><span class="nv">hrs-out</span><span class="p">.</span></code></span>
<span class="code-line"><span class="mi">01 </span><span class="nv">hrs-out-rec</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">dayname</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">XX</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">a</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">2</span><span class="p">).</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">d</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">XX</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">b</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">7</span><span class="p">).</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">hours</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">XX</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">c</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">15</span><span class="p">).</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">descr</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">50</span><span class="p">).</span></span>
<span class="code-line"><span class="mi">01 </span><span class="nv">total-rec</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">s</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">14</span><span class="p">).</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">total</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">3</span><span class="p">).</span></span>
<span class="code-line"></span></pre></div>
<p>The second file will contain two records. They can just be written directly one after the other and both will be usable with the file. </p>
<p>One thing to note is, the records defined here are all characters, that means we cannot do any calculations on them. You could in theory defined certain fields as a numeric value. I always found it more easy to copy the data twice, when needing input and output of records, so I relied on the casting-mechanisms of COBOL. </p>
<h4 id="working-storage-section">Working-Storage Section</h4>
<p>The working storage section describes the variables used in the program. In this case there is <code>nmbr</code> used for calculating the total number of hours worked in the month and we have <code>ls</code>, which is basically the working-copy of the input record. </p>
<div class="highlight"><pre><span class="code-line"><span></span><code><span class="mi">01 </span><span class="nv">ls</span><span class="p">.</span></code></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">d</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="mi">99</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">dayname</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">XX</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">hours</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="mi">99</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">descr</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">50</span><span class="p">).</span></span>
<span class="code-line"></span>
<span class="code-line"><span class="mi">01 </span><span class="nv">nmbr</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="mi">9</span><span class="p">(</span><span class="mi">3</span><span class="p">).</span></span>
<span class="code-line"></span></pre></div>
<h3 id="procedure-division_1">Procedure Division</h3>
<p>The procedure division consists of three paragraphs. The <code>bg</code> paragraph is the begin of the program, which opens the two files and initialises the data structures. <code>reed</code> reads the next record from the input file, does some reformatting and outputs the output-record to the output file. <code>e</code> is the end of the program and write the totally worked hours to the output-file. </p>
<h4 id="opening-files">Opening Files</h4>
<p>A file, which has previously been declared under File-Control in the Environment Division, can simply be opened by using the <code>OPEN</code> verb.</p>
<div class="highlight"><pre><span class="code-line"><span></span><code><span class="kr">OPEN </span><span class="o"><</span><span class="kp">mode</span><span class="o">></span><span class="w"> </span><span class="o"><</span><span class="kr">file</span><span class="o">></span><span class="p">.</span></code></span>
<span class="code-line"></span></pre></div>
<p>For simplicity some arguments are omitted. The mode can be one of the four:
- <code>INPUT</code> -- the file can only be read from
- <code>OUTPUT</code> -- the file can only be written to, the file will be created if not present, or emptied if present
- <code>I-O</code> -- the file can be read from and written to
- <code>EXTEND</code> -- the file can be written to, the file-pointer is placed after the last logical record of the file. It can only be used with <code>sequential</code> access patterns. </p>
<p>In our case, one file is opened as input, one as output. </p>
<h4 id="reading-from-files">Reading from files</h4>
<p>Reading from files is as simple as calling <code>READ</code> with the file handle afterwards. However the <code>READ</code> verb can loads of things, for example it can divert the control flow if the end of the file is reached, for example for jumping to a different place or for setting a variable. </p>
<div class="highlight"><pre><span class="code-line"><span></span><code><span class="kr">READ </span><span class="o"><</span><span class="kr">file</span><span class="o">></span><span class="w"> </span><span class="err">[</span><span class="kp">INTO </span><span class="o"><</span><span class="nv">data-structure</span><span class="o">></span><span class="err">]</span><span class="w"> </span><span class="err">[</span><span class="kp">AT</span><span class="w"> </span><span class="kr">END </span><span class="o"><</span><span class="err">statement</span><span class="o">></span><span class="err">]</span><span class="p">.</span></code></span>
<span class="code-line"></span></pre></div>
<p>When reading a file, where several data structure are attached to, the <code>INTO</code> clause can be used to identify the record, which should be filled. <code>AT END</code> specifies the statement, which should be executed at the end of the file.</p>
<p>If you want to read a file until the end, one way is to use <code>goto</code> in the <code>AT END</code> clause of the <code>READ</code> verb. However a different approach is using a <code>PERFORM</code> loop.</p>
<div class="highlight"><pre><span class="code-line"><span></span><code><span class="kr">MOVE</span><span class="w"> </span><span class="mi">0 </span><span class="kp">TO</span><span class="w"> </span><span class="nv">feof</span><span class="p">.</span></code></span>
<span class="code-line"><span class="kr">PERFORM</span><span class="w"> </span><span class="kp">UNTIL</span><span class="w"> </span><span class="nv">feof</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mi">0</span></span>
<span class="code-line"><span class="mi"> </span><span class="kr">READ</span><span class="w"> </span><span class="nv">hours</span><span class="w"> </span><span class="kp">RECORD</span><span class="w"> </span><span class="kp">INTO</span><span class="w"> </span><span class="nv">hrs-record</span><span class="w"> </span></span>
<span class="code-line"><span class="w"> </span><span class="kp">AT</span><span class="w"> </span><span class="kr">END</span><span class="w"> </span><span class="kr">MOVE</span><span class="w"> </span><span class="mi">1 </span><span class="kp">TO</span><span class="w"> </span><span class="nv">feof</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">END-READ</span></span>
<span class="code-line"><span class="kr"> </span><span class="c">*> do stuff</span></span>
<span class="code-line"><span class="kr">END-PERFORM</span><span class="p">.</span></span>
<span class="code-line"></span></pre></div>
<p>In this case the variable <code>feof</code> needs to be declared in the working-storage section. <code>PERFOM</code> loops until the condition is true, so until <code>feof</code> is bigger than 0. This will happen as soon as the end of the file is found. This way at least one could go around the use of <code>goto</code>. Please note, that the only period is followed <code>END-PERFORM</code>, as the sentence does not end until the <code>PERFORM</code>-loop is finished. </p>
<h4 id="writing-a-record-to-file">Writing a record to file</h4>
<p>Writing is also as simple as using <code>WRITE</code>. There are parameters for the <code>WRITE</code>-verb, but you will probably know when you need to use one. </p>
<div class="highlight"><pre><span class="code-line"><span></span><code><span class="kr">WRITE </span><span class="o"><</span><span class="nv">record-name</span><span class="o">></span><span class="p">.</span></code></span>
<span class="code-line"></span></pre></div>
<h4 id="closing-a-file">Closing a file</h4>
<p>Closing a file is done via the <code>CLOSE</code> verb, which takes the file handle as parameter.</p>
<div class="highlight"><pre><span class="code-line"><span></span><code><span class="kr">CLOSE </span><span class="o"><</span><span class="kr">file</span><span class="o">></span></code></span>
<span class="code-line"></span></pre></div>
<h3 id="so-what-does-it-do_1">So what does it do?</h3>
<p>The example program, which we have dived through, takes an input file which is essentially formatted like that:</p>
<div class="highlight"><pre><span class="code-line"><span></span><code><span class="mf">01</span><span class="w"> </span><span class="n">Fr</span><span class="w"> </span><span class="mf">12</span><span class="w"> </span><span class="n">hrs</span><span class="mf">.</span><span class="w"> </span><span class="n">Really</span><span class="w"> </span><span class="kr">go</span><span class="n">od</span><span class="mf">.</span></code></span>
<span class="code-line"><span class="mf">02</span><span class="w"> </span><span class="n">Sa</span><span class="w"> </span><span class="mf">32</span><span class="w"> </span><span class="n">hrs</span><span class="mf">.</span><span class="w"> </span><span class="n">Even</span><span class="w"> </span><span class="n">better</span><span class="err">!</span></span>
<span class="code-line"></span></pre></div>
<p>The program reformats it and prints the reformatted text alongside the total number of hours into an output-file:</p>
<div class="highlight"><pre><span class="code-line"><span></span><code>Fr, 01 Sep.: 12 hrs., Report: Really good.</code></span>
<span class="code-line">Sa, 02 Sep.: 32 hrs., Report: Even better!</span>
<span class="code-line"> Hours total: 044</span>
<span class="code-line"></span></pre></div>
<p>When I wrote this program it was apparently September. This program of course is of limited use, but nontheless I extended it quite a bit, to even give me input-files for gnuplot and create reports of how long I've worked in a month. </p>
<h2 id="conclusion_1">Conclusion</h2>
<p>In a way I find it quite interesting, that COBOL gives me the tools to work with files as input and output this easily. I've not seen any other language which makes it that easy for me to read and write files. C-structs would be similar, but I have to check first, where the newline symbol is myself, and that's a huge hassle. At least I have found one thing COBOL seems to be quite good at. </p>
<h2 id="references">References</h2>
<p>[1] <a href="https://de.wiktionary.org/wiki/Stechuhr">https://de.wiktionary.org/wiki/Stechuhr</a><br/>
[2] <a href="https://commons.wikimedia.org/wiki/User:Ludek">https://commons.wikimedia.org/wiki/User:Ludek</a></p>Learning COBOL with Examples - Part 1: Basics and Hello World2019-02-04T20:08:00+01:002019-02-04T20:08:00+01:00snaumstag:www.snaums.de,2019-02-04:/informatik/learning-cobol-with-examples-01.html<p>Learning a new programming language and specially a really really old and obscure one is hard. This is especially true with COBOL since most documentation is extremely old, outdated and there are essentially no other users. This means just searching for your problem on any arbitrary search engine will probably …</p><p>Learning a new programming language and specially a really really old and obscure one is hard. This is especially true with COBOL since most documentation is extremely old, outdated and there are essentially no other users. This means just searching for your problem on any arbitrary search engine will probably not solve your issue, like it would with C or C++ problems. However learning a new language can also be fun and is educational, as there are many old programs out there written in COBOL. </p>
<p>These upcoming blog entries and this one is there to help get you off the ground. I'm not saying, that COBOL is my favourite language and I'm not saying that my code it good. But I still hope these posts will help you understand some basics of the COBOL language. I'm gonna spare you the historic parts. </p>
<p>I'm a C programmer. My background is in Operating Systems and bare-metal programming. </p>
<p>The thumbnail-image is from [<a href="http://deacademic.com/dic.nsf/dewiki/873823">3</a>].</p>
<h2 id="compiler">Compiler</h2>
<p>You will need a compiler, which translates the COBOL source code into natively executeable programs. I'm using GnuCOBOL [<a href="https://open-cobol.sourceforge.io/">1</a>]. On their website they also have handy reference sheets if you ever need to look up the grammar of COBOL. The Forum on SourceForge is also one of the only places you find people asking for COBOL related problems. </p>
<p>In Arch Linux, gnu-cobol is not in the official repositories, but it can be found in an AUR [<a href="https://aur.archlinux.org/packages/gnu-cobol/">2</a>]. Your distribution will probably also have a package ready for gnu-cobol. </p>
<p>I'm going to use a few flags as default, unless stated otherwise. </p>
<div class="highlight"><pre><span class="code-line"><span></span><code>cobc -x --free --Wall inputfile.cob</code></span>
<span class="code-line"></span></pre></div>
<p>The ''-x'' instructs the compiler to create an executable file. ''--free'' will make it use the free form of COBOL. Old versions of COBOL used a set form on punch cards, where the first so-and-so characters where the line number, then a special field for comments, code, bla. To make COBOL look more like a modern-ish programming language I'm going to use the free form, so I'm able to have very long lines and start at column 0. And ''--Wall'' will print out all warning messages the compiler can produce. This will help improving our code. </p>
<h2 id="a-first-very-very-simple-program">A first very very simple program</h2>
<p>This is a simple program, displaying "Hello World" and the truth about everything. It is more than a normal "Hello World" program to show you more Divisions of a COBOL program. </p>
<div class="highlight"><pre><span class="code-line"><span></span><code><span class="kr">IDENTIFICATION</span><span class="w"> </span><span class="kr">DIVISION</span><span class="p">.</span></code></span>
<span class="code-line"><span class="kr">PROGRAM-ID</span><span class="p">.</span><span class="w"> </span><span class="nv">truth</span><span class="p">.</span></span>
<span class="code-line"></span>
<span class="code-line"><span class="kr">ENVIRONMENT</span><span class="w"> </span><span class="kr">DIVISION</span><span class="p">.</span></span>
<span class="code-line"><span class="kr">CONFIGURATION</span><span class="w"> </span><span class="kr">SECTION</span><span class="p">.</span></span>
<span class="code-line"><span class="kp">SOURCE-COMPUTER</span><span class="p">.</span><span class="w"> </span><span class="nv">IBM-PC</span><span class="p">.</span></span>
<span class="code-line"><span class="kp">OBJECT-COMPUTER</span><span class="p">.</span><span class="w"> </span><span class="nv">IBM-PC</span><span class="p">.</span></span>
<span class="code-line"></span>
<span class="code-line"><span class="kr">DATA</span><span class="w"> </span><span class="kr">DIVISION</span><span class="p">.</span></span>
<span class="code-line"><span class="kr">WORKING-STORAGE</span><span class="w"> </span><span class="kr">SECTION</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">01 </span><span class="nv">truth</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="mi">99</span><span class="p">.</span></span>
<span class="code-line"></span>
<span class="code-line"><span class="kr">PROCEDURE</span><span class="w"> </span><span class="kr">DIVISION</span><span class="p">.</span></span>
<span class="code-line"><span class="nv">begin</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">DISPLAY </span><span class="s2">"Hello World"</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">MOVE</span><span class="w"> </span><span class="mi">42 </span><span class="kp">TO</span><span class="w"> </span><span class="nv">truth</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">DISPLAY</span><span class="w"> </span><span class="nv">truth</span><span class="p">.</span></span>
<span class="code-line"><span class="kr">EXIT</span><span class="w"> </span><span class="kp">PROGRAM</span><span class="p">.</span></span>
<span class="code-line"></span></pre></div>
<p>The first things, that will probably hit your eye is the fact, that the code is divided into so called Divisions. In Divisions you have Sections, then Paragraphs, Sentences, Verbs and Characters. COBOL was designed to be quite close to the English language, so you will probably understand most of the operations already. </p>
<p>You see four divisions in the code above:</p>
<ol>
<li>IDENTIFICATION DIVISION - for identifying the program. There is not much of use in there today. The PROGRAM-ID has to be set to be usable from other programs (a topic for another time). </li>
<li>ENVIRONMENT DIVISION - for identifying the environment. The configuration section is there for defining source and target computers. This is not really relevant anymore and can be left out of your programs easily. However the Environment division will be used later for File I/O. </li>
<li>DATA DIVISION - your variables and data structures will be defined here (inside the WORKING-STORAGE SECTION). </li>
<li>PROCEDURE DIVISION - this is where the actual code is. </li>
</ol>
<h3 id="defining-some-variables-data-division">Defining some Variables (Data Division)</h3>
<p>In the program above the DATA DIVISION and the PROCEDURE DIVISION is interesting. Let's start with the DATA DIVISION, as I am defined a variable in there, named ''truth''. When defining data structures, the syntax is as follows:</p>
<div class="highlight"><pre><span class="code-line"><span></span><code><span class="o"><</span><span class="k">level</span><span class="o">></span><span class="w"> </span><span class="o"><</span><span class="n">name</span><span class="o">></span><span class="w"> </span><span class="n">PIC</span><span class="w"> </span><span class="o">[</span><span class="n">IS</span><span class="o">]</span><span class="w"> </span><span class="o"><</span><span class="n">type</span><span class="o">></span><span class="w"> </span><span class="o">[</span><span class="n">VALUE [IS</span><span class="o">]</span><span class="w"> </span><span class="o"><</span><span class="k">value</span><span class="o">></span><span class="err">]</span><span class="p">.</span></code></span>
<span class="code-line"></span></pre></div>
<p>There are more statements, that can be made, but they are omitted here. COBOL works a bit differently when describing data structures than other languages. Basically nearly everything in COBOL is a record (or struct). The level indicates, which level this entry is on. You can have anything from 01 to 49, 66, 77 and 88 in there. </p>
<table>
<thead>
<tr>
<th>Level</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td>01</td>
<td>record level, top level</td>
</tr>
<tr>
<td>02-49</td>
<td>elementary and sub-types</td>
</tr>
<tr>
<td>66</td>
<td>rename clause</td>
</tr>
<tr>
<td>77</td>
<td>items, which cannot be sub-divided</td>
</tr>
<tr>
<td>88</td>
<td>condition name entry</td>
</tr>
</tbody>
</table>
<p>Let's focus on the levels 01 to 49. With the level one can create deeper data structures. Smaller numbers are names for the group of variables of the next lower numbers. For example one can build a structure as follows:</p>
<div class="highlight"><pre><span class="code-line"><span></span><code><span class="kr">DATA</span><span class="w"> </span><span class="kr">DIVISION</span><span class="p">.</span></code></span>
<span class="code-line"><span class="kr">WORKING-STORAGE</span><span class="w"> </span><span class="kr">SECTION</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">01 </span><span class="nv">person</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">name</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="nv">X</span><span class="p">(</span><span class="mi">20</span><span class="p">).</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">02 </span><span class="nv">tel</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="mi">9</span><span class="p">(</span><span class="mi">10</span><span class="p">).</span></span>
<span class="code-line"></span></pre></div>
<p>The name is any arbitrary name you want to give to the variable. The PIC clause identifies the data type of the variable. A variable in COBOL is always compounded. You can have one of always the same types, but you can define ones with several different types in different positions, so you can have numbers with signs or decide where the comma is. But you have to do that statically. </p>
<p>So let's say you want to define a variable, which can store a year with four numbers, then the following could a valid definition. Both of the statements are identical. </p>
<div class="highlight"><pre><span class="code-line"><span></span><code><span class="kr">DATA</span><span class="w"> </span><span class="kr">DIVISION</span><span class="p">.</span></code></span>
<span class="code-line"><span class="kr">WORKING-STORAGE</span><span class="w"> </span><span class="kr">SECTION</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">01 </span><span class="nv">year</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="mi">9999</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="mi">01 </span><span class="nv">year2</span><span class="w"> </span><span class="kt">PIC IS</span><span class="w"> </span><span class="mi">9</span><span class="p">(</span><span class="mi">4</span><span class="p">).</span><span class="w"> </span></span>
<span class="code-line"></span></pre></div>
<p>Now if you know other programming languages already, the notation is a bit weird. There is no data type, is there? Oh, yes, there is. But it is written down differently than in C. As said, the PIC-clause determines the type of the variable. The following types are available:</p>
<table>
<thead>
<tr>
<th>Symbol</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td>9</td>
<td>Numeric</td>
</tr>
<tr>
<td>A</td>
<td>Alphabetic</td>
</tr>
<tr>
<td>P</td>
<td>Decimal</td>
</tr>
<tr>
<td>S</td>
<td>Sign</td>
</tr>
<tr>
<td>V</td>
<td>Decimal point (implicit)</td>
</tr>
<tr>
<td>X</td>
<td>Alphanumeric</td>
</tr>
</tbody>
</table>
<p>Among other things, there is a VALUE-clause after PIC, there can be even more. The VALUE clause sets a preset value, the variable will have when the program starts. </p>
<h3 id="writing-a-program-procedure-division">Writing a Program (Procedure Division)</h3>
<p>Now let's take a gander at the Procedure Division of the above example.</p>
<div class="highlight"><pre><span class="code-line"><span></span><code><span class="kr">PROCEDURE</span><span class="w"> </span><span class="kr">DIVISION</span><span class="p">.</span></code></span>
<span class="code-line"><span class="nv">begin</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">DISPLAY </span><span class="s2">"Hello World"</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">MOVE</span><span class="w"> </span><span class="mi">42 </span><span class="kp">TO</span><span class="w"> </span><span class="nv">truth</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">DISPLAY</span><span class="w"> </span><span class="nv">truth</span><span class="p">.</span></span>
<span class="code-line"><span class="w"> </span><span class="kr">STOP</span><span class="w"> </span><span class="kp">RUN</span><span class="p">.</span></span>
<span class="code-line"></span></pre></div>
<p>It consists of two notable things - the first is the label ''begin''. This is a label like one might know from Assembly-code or really really bad C-code. This allows your code to jump to that exact place with the help of the ''GO TO'' verb. But more on that later. </p>
<p>Then the statements basically look the same. There is a Verb and an/several operand/s. ''DISPLAY'' will print the string/object after it to stdout, ''MOVE'' is a copying operator, like the ''mov''-instruction in most ISAs. The direction of the move is written clearly in the rest of the sentence. ''42 TO truth'' - so you probably already knew what this sentence did, before reading this far. ''STOP RUN'' stops the program, much like ''exit()'' in C. </p>
<p>There are loads of Verbs and Builtin function in modern COBOL, so listing them all here is not only redundant but also nearly impossible. </p>
<h3 id="comments">Comments</h3>
<p>One really important thing are comments. While being omitted in the above example, one can use the following syntax to comment lines.</p>
<div class="highlight"><pre><span class="code-line"><span></span><code><span class="c">*> This is a comment, which will be ignored by the compiler</span></code></span>
<span class="code-line"><span class="kr">DISPLAY </span><span class="s2">"HELLO WORLD"</span><span class="w"> </span><span class="c">*> Now Display will be compiled, but this comment not</span></span>
<span class="code-line"></span></pre></div>
<h2 id="conclusion_1">Conclusion</h2>
<p>So there we have it. This post showed a very simple COBOL program and tried to describe the concepts generically. If you find errors, don't hesitate to contact me (English or German, both fine). </p>
<h2 id="references">References</h2>
<p>[1] <a href="https://open-cobol.sourceforge.io/">https://open-cobol.sourceforge.io/</a><br/>
[2] <a href="https://aur.archlinux.org/packages/gnu-cobol/">https://aur.archlinux.org/packages/gnu-cobol/</a><br/>
[3] <a href="http://deacademic.com/dic.nsf/dewiki/873823">http://deacademic.com/dic.nsf/dewiki/873823</a></p>