Debugging GnuCOBOL Using WITH DEBUGGING MODE

Prior to COBOL85, COBOL had its own debug module accessed in the DECLARATIVES. This was removed in the 1985 standard. It appears gnuCOBOL still supports the older debugging, but given gdb can be used (next blog post), I won’t go down that route.

Instead, I will examine the debugging that COBOL85 does still natively support.

Debugging Lines

When debugging is enabled, lines with a D in column 7 (fixed format) or start with >>D (free format) are compiled. If not enabled, they are not compiled.

>>D display "debugging line hit".

OR

      D    display "debugging line hit".

Normally one indicates these lines should be compiled using by specifying WITH DEBUGGING MODE in the SOURCE-COMPUTER paragraph:

source-computer. 
    x86                                 with debugging mode.

However, you can leave this clause off, and use the -fdebugging-line switch when invoking the compiler.

Here is code and a sample run using debugging statements:

C:\cobol\oldDebugging>cobc -t- -fdebugging-line -xj sw0debug.cbl
GnuCOBOL 3.1-rc1.0      sw0debug.cbl         Mon Aug 31 15:31:40 2020  Page 0001

LINE    PG/LN  A...B............................................................

000001         >>source free
000002  identification division.
000003  program-id.
000004      test.
000005
000006  environment division.
000007  configuration section.
000008  source-computer.
000009      x86.
000010
000011  procedure division.
000012
000013  >>D display "debugging line hit".
000014      display "non debugging line hit".
000015
000016      stop run.


0 warnings in compilation group
0 errors in compilation group
debugging line hit
non debugging line hit

Using SW0 to Control Debugging

When I was writing COBOL on the HP3000, I almost always wanted my debugging lines compiled. If there was a problem, I didn’t want to have to recompile code. This was probably because minicomputers were so slow and compilers took so many resources, each programmer might be lucky to get in 3 compiles a day. I often worked nights just so I wouldn’t have to fight as much for compile time!

I needed a simple mechanism to enable/disable debugging at run time rather than compile time. There were several ways to do this on the HP3000 and I did it using the switch register with SPECIAL-NAMES of SW0 and I see gnuCOBOL supports a switch register as well.

The first HP3000 I programmed (Series III) had an actual 16 bit switch register on the front panel that primarily was used to enter a start address to boot the system. However, it could also be read programmatically by COBOL.

The switch register went away on later models, but there needed to be a way to continue to support programs that made use of that register. On the HP3000, this was done by passing the value of the 16 bit switch register, in decimal, to the program in the PARM keyword such as:

:RUN MYPROG;PARM=1

This would set bit 0 of the switch register to 1 rather than 0. (PARM=2 would have set switch register bit 1 to 1). Thus, when I ran a COBOL program on the HP3000 with PARM=1, it would display debugging so I would not have to recompile.

Here is the modified program that uses the SWITCH-0 register in special names to create the condition-name called fl-debug which is tested to determine is debugging output should be displayed. Since SWITCH-0 has not yet been set fl-debug will return false and the debugging will not be displayed:

C:\cobol\oldDebugging>cobc -t- -xj sw0debug.cbl
GnuCOBOL 3.1-rc1.0      sw0debug.cbl         Mon Aug 31 16:09:01 2020  Page 0001

LINE    PG/LN  A...B............................................................

000001         >>source free
000002  identification division.
000003  program-id.
000004      test.
000005
000006  environment division.
000007  configuration section.
000008  source-computer.
000009      x86                                 with debugging mode.
000010  special-names.
000011      SWITCH-0                            is fl-debug-flag,
000012          on status                       is fl-debug.
000013
000014  procedure division.
000015
000016  >>D if fl-debug,
000017  >>D     display "debugging line hit".
000018
000019      display "non debugging line hit".
000020
000021      stop run.


0 warnings in compilation group
0 errors in compilation group
non debugging line hit

For gnuCOBOL, the SWITCH-0 register is set to 1 by setting an environment variable:

C:\cobol\oldDebugging>set COB_SWITCH_0=on

C:\cobol\oldDebugging>sw0debug.exe
debugging line hit
non debugging line hit

Setting COB_SWITCH_0 to off will disable the debugging.

Next time I’ll discuss using gdb with gnuCOBOL. Compared to using a modern debugger like gdb, having only DISPLAY is pretty primitive, but can still work. I still have to debug MCU code just using printf or even worse, just flashing a LED.

Posted in c-gnuCOBOL | Tagged | Leave a comment

Calling Pascal procedures to Manipulate the GnuCOBOL String Data Structure

Last episode saw the definition of a string data structure for COBOL. This episode will show how to write Pascal Code to manipulate the string data structure (cst-string).

Using these examples, it would be easy enough to implement any needed string processing procedure.

I have created 3 Pascal procedures: cstset, cstdeb, and cstrightj.

cstset is used to initialize cst-string by moving text from a buffer into cst-string and setting the cst-len appropriately. It replaces the COBOL-only code I did in the prior post.

cstdeb (deblank) will remove leading and trailing spaces from cst-string.

cstrightj (right justify) will right justify the text in cst-string using the specified field width.

To make using these procedures easier, there is a copy book (.cpy file) for each call: cfCstSet, cfCstDeb, and cfCstRightJ.

Rather than describe all of the parts, the following file contains a listing of the Pascal program, commands to compile and execute the Pascal and COBOL code with the resulting run’s output, and finally the compiler’s listing of the COBOL code.

All Listings

 

Posted in c-gnuCOBOL | Tagged , | Leave a comment

A String Data Structure for GnuCOBOL

When I started to learn COBOL in the late 70’s, HP BASIC was my primary language. BASIC is adept at handling strings. As I quickly found, COBOL (particularly the 1968 standard I was using), was not.

I know there are some string processing functions available in gnuCOBOL such as TRIM. For this post, I want to implement the string data structure I used for all of my string processing needs.

Simple Example of Lack of Strings

Here is a very rudimentary example of a problem that occurs by not having some type of string data structure. Say you define 2 variables:

01  buffer                     pic x(40).
01  formattedAmount            pic ---,--9.99.

Then initialize and output them:

move "JOHN SMITH"             to buffer.
move 1.98                     to formattedAmount.

display ">", buffer, "|", formattedAmount, "<".

The display would show:

>JOHN SMITH                              |      1.98<

Lining up data in columns might be suitable for a line printer but is ugly on a terminal. If you want to see the output as

>JOHN SMITH|1.98<

it really wasn’t doable.

A COBOL String Data Structure

At my first job, on a DEC-10, I stumbled upon a simple way to control how much of a string buffer could be displayed:

01 len                           pic s9(4), comp.
01 str.
   03  str-byte                  pic x,
         occurs                  0 to 80 times,
         depending on            len.

To display str without trailing spaces, I just needed to:

move 80                         to len.
move "JOHN SMITH"               to str.
move 10                         to len.
display ">", str, "<".

>JOHN SMITH<

Having to move 80 to len first was a bit clumsy. In more careful reading of the manual I found I could create the following data structure which became my standard COBOL string data structure:

01  cst-string.
    03  cst-max                            pic s9(4), comp, value 80.
    03  cst-len                            pic s9(4), comp.
    03  cst-in                             pic x(80).
    03  cst-out redefines                  cst-in.
        05  cst-byte                       pic x,
                occurs                     0 to 80 times,
                depending on               cst-len.

This worked like a charm. Now to setup a string it just required this:

move "JOHN SMITH"                         to str-in.
move 10                                   to str-len.
display ">", str-out, "<".

When I moved to a job programming HP3000’s in COBOL, I took this idea with me where I used it for several decades. More than likely some of that code is still running.

If you are a COBOL programmer, you may be saying “WHOA, you can’t do that!” Per the COBOL standards, you cannot redefine a variable length field!

That is true in gnuCOBOL and is true according to the ’74 and ’85 standard manuals I have. BUT it did work on the DEC10 and the HP3000 COBOL compilers.

Making the COBOL String Structure Work for gnuCOBOL

I screwed around with trying to get past that limitation for a while and finally gave up. Instead gnuCOBOL requires this data structure:

01  cst-string.
    03  cst-max                                   binary-short unsigned, value 256.
    03  cst-len                                   binary-short unsigned.
    03  cst-out.
        05 cst-byte                               pic x,
             occurs                               0 to 256 times,
             depending on                         cst-len.

The downside to this structure is you cannot move a string to it without first setting cst-len to cst-max before initializing cst-out. So to create a string you would do this:

move cst-max                                     to cst-len.
move "JOHN SMITH"                                to cst-out.
compute cst-len = 
    function length( 
        function trim( cst-out, trailing)).
if cst-len = 1 and cst-byte(1) = space then
    move zero                                    to cst-len.

Still kind of a lot of work to do, but one can create a copy book code fragment to do the work:

       >>source free
*>cfCstSet:
*>  01/31/12:   DWH.                 
*>              Created for openCOBOL.            
*>  08/15/20:   DWH.
*>              Updated for gnuCOBOL.
                                                                  
*>--------------------------------------------------------------   
*>    COPY cfstrset
*>    REPLACING cst-in BY <literal|word>].                           
*>--------------------------------------------------------------   
                                                                  
*>    openCOBOL doesn't allow my old STR string structure. The new
*>    structure requires the following code frag to move something
*>    into the structure and set the size.

*>    This code fragment can be copied anywhere such as:
*>        if 1=1 then
*>            copy cfCstSet replacing cst-in with "test";
*>        else,
*>            next sentence.
                             
    move cst-max                        to cst-len;
    move cst-in                         to cst-out;
    compute cst-len = 
        function length( 
            function trim( cst-out, trailing));
    if cst-len = 1 and cst-byte(1) = space then
        move zero                      to cst-len;
    end-if;

Now, to move create a string of “JOHN SMITH”, I just:

copy cfcstset,
    replacing cst-in by "JOHN SMITH".

Here is a listing of an example program (with expanded copy books) so you can see everything:

GnuCOBOL 3.1-rc1.0      cfcstsetEx.cbl       Sun Aug 16 15:21:34 2020  Page 0001
000011
LINE    PG/LN  A...B............................................................
000013
000001         >>SOURCE FREE
000002  identification division.                by "JOHN SMITH".
000003  program-id.urce free
000004      cfcstsetEx.
000005
000006  data division.  
000007
000008  working-storage section.
000009
000010  copy wscst.
000001C        >>SOURCE FREE
000002C *>wscst
000003C *>    AA0000: 01/08/88:    DWH.
000004C *>            STR COBOL string routine data names.
000005C *>    AA0001: 01/31/12:    DWH.
000006C *>            Converted to run in OpenCobol.                                   
000007C
000008C *>--------------------------------------------------------------
000009C *>    COPY wscst
000010C *>    [REPLACING 256 BY ].
000011C *>--------------------------------------------------------------ng
000012C *>    into the structure and set the size.
000013C *>    STANDARD COBOL STRING DATA STRUCTURE.
000014C *>    You can change the maximum string size by using the
000015C *>    REPLACING clause.
000016C *>            copy cfCstSet replacing cst-in with "test";
000017C 01  cst-string.
000018C     03  cst-max                         binary-short unsigned, value 256
000018+ .
000019C     03  cst-len                         binary-short unsigned.
000020C     03  cst-out.MITH" to cst-out;
000021C         05  cst-byte                    pic x,
000022C            occurs                       0 to 256 times,
000023C            depending on                 cst-len.
000024C
000011
000012  procedure division.
000013
000014      copy cfCstSet
000015          replacing cst-in                by "JOHN SMITH".
000001C        >>source free
000002C *>cfCstSet:
000003C *>  01/31/12:   DWH.
000004C *>              Created for openCOBOL.
000005C *>  08/15/20:   DWH.
000006C *>              Updated for gnuCOBOL.
000007C
000008C *>--------------------------------------------------------------
000009C *>    COPY cfstrset
000010C *>    REPLACING cst-in BY <literal|word>].
000011C *>--------------------------------------------------------------
000012C
GnuCOBOL 3.1-rc1.0      cfcstsetEx.cbl       Sun Aug 16 15:21:34 2020  Page 0002

LINE    PG/LN  A...B............................................................

000013C *>    openCOBOL doesn't allow my old STR string structure. The new
000014C *>    structure requires the following code frag to move something
000015C *>    into the structure and set the size.
000016C
000017C *>    This code fragment can be copied anywhere such as:
000018C *>        if 1=1 then
000019C *>            copy cfCstSet replacing cst-in with "test";
000020C *>        else,
000021C *>            next sentence.
000022C
000023C     move cst-max                        to cst-len;
000024C     move "JOHN SMITH" to cst-out;
000025C     compute cst-len =
000026C         function length(
000027C             function trim( cst-out, trailing));
000028C     if cst-len = 1 and cst-byte(1) = space then
000029C         move zero                      to cst-len;
000030C     end-if;
000031C
000032C
000016
000017      display ">", cst-out, "<".
000018
000019      stop run.


0 warnings in compilation group
0 errors in compilation group

And the resulting output:

>JOHN SMITH<

Next time, I will show how to pass the COBOL string data structure to Pascal and let it do some basic string processing functions.

Posted in c-gnuCOBOL | Tagged | Leave a comment

Parameter Passing when calling Free Pascal from GnuCOBOL

In our last exciting episode of gnuCOBOL, I showed the rudiments of calling a Pascal program from COBOL. Today I will delve deeper into passing parameters.

Example Code

Rather than put a lot of code straight into this post, here are links to a COBOL program and Pascal procedures that perform many different types of calls:

The Primary COBOL program.

The Primary Pascal routines.

The output to this program is:

calling Pascal
Hello World!
@proc0
@proc1. p1: 1
@proc2. p1: 1; p2: 2
@func1. p1: 1
@procbyref. p1: 1; p2: 2
func1 returned: +0002
@procrec: memory dump of rec:
0000: 534D 4954 4820 2020 2020 2020 2020 2020 2020 2020 SMITH
0014: 2020 2020 2020 2020 2020 4A4F 484E 2020 2020 2020 JOHN
0028: 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020
003C: 0026 0001 2345 678C .&..#Eg.
called Pascal

Matching Data Types

By default, COBOL does a pretty good job of hiding underlying data types. It is meant to be a machine dependent language and it does a great job of it where data types are concerned.

If I want a 4 digit number I use PIC 9999. If it might be negative, then I use PIC S9999. If I will be doing a lot of computations with it then I say PIC S9999, COMP. I never have to think about which type of integer I need.

You can call Pascal directly with variables defined using PIC clauses, but it sometimes it takes some trial and error. To pass numbers to Pascal you are better off using gnuCOBOL’s numeric usage defintions. In the GnuCOBOL 2.2 Nov 2017 manual, these can be found in section 9.8.3 such as:

So rather than

01  mydataP                        pic s9(4), comp.

use

01  mydataI                       binary-short signed.

Here are a couple of the more esoteric issues one could have when converting from COBOL PIC to numeric usage types: size errors and implied decimal points.

Size Errors

There can be a problem with mixing PIC variables and usage type variables. Moving the above mydataI to mydataP can cause leading digit truncation.

For example, if mydataI contains 12345 (it can contain up to 32767) and is moved to the 4 digit mydataP field, mydataP will contain 2345, not 12345.

If you must move mydataI to mydataP do so using compute like this:

compute mydataP = mydataI,
    on size error,
        display "Overflow occurred!!".

A sample program showing the various types of moves between these two data types can be seen here.

The output from this program:

After p(1234) to i move:
p: +1234
i: +01234
After i(9876) to p move:
i: +09876
p: +9876
After i(12345) to p move:
i: +12345
p: +2345
Trying compute:
Overflow occurred!!

Implied decimal point

There are several reasons I like COBOL and one is that it handles dollar & cents so easily with perfect precision. One should NEVER put dollar amounts into a floating point data type regardless of the language! That leaves (in most lanaguages) just integers. That means the programmer is responsible for knowing that

salary: integer;

must contain pennies. The programmer is responsible for knowing where the decimal point is at. If he wants more precision than pennies then he is responsible for that as well. Addition/subtraction is hard enough, but multiplication and division are even more cumbersome.

In Pascal, if  I want to put $1000 into salary I must use 10,000 pennies:

salary := 100000;

In COBOL, you define salary as:

77  Salary      PIC S9(6)v99, comp.

The compiler determines the correct underlying data type to use. Note that ‘v’ means that is where an implied decimal point is located. When you say:

move 1000 to salary.

you get a Salary of $1000.00 as you would expect.

If you must pass salary to a Pascal program you either need to determine the underlying data type used, or move it to a numeric usage field.

s9(6)v99 contains 7 digits which will fit in a 32bit integer just fine so I can use

01  salaryP                     pic s9(6)v99.
01  salaryI                     usage binary-int signed.

In this test program, I move salaryP to salaryI and call a Pascal routine to simply display it.

The COBOL code

The Pascal Code

When run, the output is:

size of salaryI: 4
size of salaryP: 4
Passing salaryP(+123456.78) to prtSalary:
@prtSalary. Salary: 12345678
Passing salaryI(+0000123456) to prtSalary:
@prtSalary. Salary: 123456

There is a REALLY IMPORTANT side effect highlighted above!!

After moving salaryP to salaryI, the fractional part of salaryP is lost:

move 123456.78 to salaryP.
move salaryP to salaryI.

As seen in the program output above, salaryI contains 123456 after the move NOT 12345678.  To retain the fractional part you would  need to compute rather than move:

compute salaryI = salaryP * 100.

This would result in salaryI of 12345678 being passed to prtSalary.

It seems to me, when mixing variables defined using PIC COMP and moving them to/from numeric usage variables you want to use COMPUTE and NOT MOVE.

In the real world, I can’t ever recall wanting to pass dollar amounts to a non-COBOL subroutine. COBOL excels at handling dollar amounts, so use it instead!

Endian Issues

When I initially did this testing and write-up, I didn’t realize there were endian issues until the first time I passed an integer to pascal and found it was garbage.

When using PIC S9(n), COMP, gnuCOBOL stores and passes the field as big-endian in keeping with the format of old mainframe storage formats.

When you pass that field to Pascal as an integer, it will expect it to be in little-endian format. The value isn’t so the pascal routine receives what amounts to garbage.

In summary, using COMP or BINARY for gnuCOBOL results in big-endian variables. Using BINARY-SHORT or other BINARY- formats will result in little-endian variables. So, make sure you use the BINARY- numeric usage clause on any integer that will be passed to an external Pascal routine.

At this time, there is an explanation in the gnuCOBOL FAQ here.

Matching Parameter Passing Methods

Back when I was coding in HP’s COBOL85, there was only one way to pass variables to the outside world: BY REFERENCE. GnuCOBOL allows by reference, by value, and by contents (see section 9.6.1.1 of the gnuCOBOL manual).

Because by reference was the only way you once could pass parameters, I would have expected that to be the default, but I have found in these test programs you must specify how to pass each parameter.

call "procrec",
    using       by reference    test-rec,
                by value        function byte-length(test-rec).

Dealing with Function Returns

gnuCOBOL the ability to receive integers from Pascal functions.

Thus, if you want to return a numerical value in a Pascal function, do so using this type of definition:

function func: integer;

You would call func in this manner:

01  i-long                    binary-long signed.

call "func"
    returning                 i-long.

I have been able to return long and short integers in this manner.

Here is some example code:

COBOL Program

Pascal Routines

The results of the program were:

Value of returned in i-long: +0123456789
Value of returned in i-short: +12345
Calling func w/o a return:
done

Returning Omitted

If COBOL calls a Pascal function, but the functional result is not used, then you must use omitted:

call "func"
    returning omitted.

I found that if you left the “returning omitted” clause off, the linker would not find the external “func” probably because the parameters didn’t match up properly.

Passing COBOL Records

The primary test COBOL program at the top of this blog entry contains a record to be passed to Pascal defined as:

01  test-rec.
    03   lastname                           pic x(30).
    03   firstname                          pic x(30).
    03   age                                pic s9(4), comp.
    03   salary                             pic s9(9)v99, comp-3.

Calling the pascal program is simple:

call "procrec",
    using                           by reference test-rec,
                                    by value     function byte-length(test-rec).

In the Pascal procedure, there are 2 ways to handle the incoming test-rec. If I need to get to every field I would define a Pascal record to do so along the lines of:

Type
  recT                    = record
    lastname              : packed array of char[1..30];
    firstname             : packed array of char[1..30];
    age                   : smallint;
    salary                : ??
    end;

OK, off the top of my head, I don’t know exactly how large this COMP-3 field is in Pascal, I’d have to look it up, but I’m just going to represent the record as an array of bytes so I use:

type 
    aobT                                = array of byte;

procedure procrec(
    var rec                             : aobT;
    reclen                              : integer
    );

In this sample program, I just want to dump the entire record, not read any specific fields, so an array of bytes works just fine. When I dump this record I find I have:

0000: 534D 4954 4820 2020 2020 2020 2020 2020 2020 2020 SMITH
0014: 2020 2020 2020 2020 2020 4A4F 484E 2020 2020 2020 JOHN
0028: 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020
003C: 0026 0001 2345 678C .&..#Eg.

I can also see from this dump that the comp-3 field takes 6 bytes or 12 nibbles (each digit and the sign takes a nibble).

Strings

I have been slowly working toward strings as that is my primary interest in calling Pascal routines. I have a very large Pascal string processing library that would be nice to access. That will be covered in my next post.

Posted in c-gnuCOBOL | Tagged , | Leave a comment

Calling Free Pascal Procedures from GnuCOBOL in Windows

I’m slowly working through various experiments with gnuCOBOL. One experiment is to call Pascal code from a gnuCOBOL program. The gnuCOBOL FAQ has an example, but I presume this only works for Linux. It definitely doesn’t work for MinGW/Windows.

I spent entirely too much time trying to get this experiment to work; thus, the blog post. I don’t want to forget how to do this.

The sample Pascal program (pascalCode.pas):

library pascalCode;
{$mode objfpc}{$H+}

procedure testp;
begin
writeln('Hello World!');
end;

procedure zippy;
begin
writeln('zippy');
end; // zippy

exports
    testp,
    zippy;

begin
end.

Here is the COBOL program(test.cbl):

       >>SOURCE FREE
identification division.
program-id.
    test.

procedure division.

0000-mainline.

    display "calling Pascal".
    call "testp",
        returning omitted.
    call "zippy",
        returning omitted.
    display "called Pascal".

0099-exit.

    stop run.

To compile and run:

export COB_PRE_LOAD=pascalCode
fpc pascalCode.pas
cobc -x test.cbl -L. -l:pascalCode.dll
./test

and the results:

./test
calling Pascal
Hello World!
zippy
called Pascal

 

Posted in c-gnuCOBOL | Tagged , | Leave a comment

Installing gnuCOBOL into MinGW

I’ve been away from this project for several months and managed to forget exactly how I was supposed to invoke the COBOL compiler. I had made a note in the post
Installing gnuCOBOL on Windows, but that just tells where to find the compiler, not how to incorporate it into minGW.

I decided to incorporate gnuCOBOL into minGW again and document it for future use.

Download the Compiler

You can find the latest MinGW version at Arnold Trembley’s website. I want the version:

(NEW) GnuCOBOL 3.1-rc1 (30JUN2020) MinGW compiler for Windows XP/7/8/10 with COBOL ReportWriter. Includes VBISAM 2.0.1 for Indexed Sequential file access support, GMP 6.2.0, and PDCurses 4.1.99 (17.0 megabytes). Rename .7z to .exe for self-extracting archive.

If this website goes away, the above file (which will go out of date quickly) can also be found here.

Install the Compiler

I assume you have already installed MinGW. My notes on doing so can be found here.

Arnold Trembley’s version of gnuCOBOL is configured to reside at c:\mingw\share. Therefore, create the directory c:\mingw\share, and unzip the contects of the gnuCOBOL zip file into it.

Add C:\MinGW\share\gnucobol\bin to your path.

This almost is done. There is one problem yet: the path will be setup to run GCC out of /mingw/bin and that will cause a problem (mingw’s gcc compiler will be unable to find <libcobol.h>. You need to run it out of /mingw/share/gnucobol/bin.

To do this you must edit /etc/profile and insert /mingw/share/gnucobol/bin as shown:

# My decision to add a . to the PATH and as the first item in the path list
# is to mimick the Win32 method of finding executables.
#
# I filter the PATH value setting in order to get ready for self hosting the
# MSYS runtime and wanting different paths searched first for files.
if [ $MSYSTEM == MINGW32 ]; then
export PATH=".:/mingw/share/gnucobol/bin:/usr/local/bin:/mingw/bin:/bin:$PATH"
else
export PATH=".:/usr/local/bin:/bin:/mingw/bin:$PATH"
fi

To Test

Start minGW bash and type cobc -v

chiefdude10/~:cobc -v cobc (GnuCOBOL) 3.1-rc1.0
Built Jul 04 2020 17:17:54 Packaged Jul 01 2020 00:39:30 UTC
C version (MinGW) "6.3.0"
loading standard configuration file 'default.conf'
cobc: error: no input files
chiefdude10/~:

You should see the bold line above, indicating that the default configuration is loaded.

The same will work in CMD:

C:\>cobc -v
cobc (GnuCOBOL) 3.1-rc1.0
Built Jul 04 2020 17:17:54 Packaged Jul 01 2020 00:39:30 UTC
C version (MinGW) "6.3.0"
loading standard configuration file 'default.conf'
cobc: error: no input files

C:\>

You now have a working gnuCOBOL compiler!

To test, I created the following file (there are 7 spaces before ‘>>SOURCE FREE’):

       >>SOURCE FREE
*> Sample COBOL program
IDENTIFICATION DIVISION.
PROGRAM-ID. hello.
DATA DIVISION.
PROCEDURE DIVISION.
DISPLAY "Hello, world!".
STOP RUN.

To compile and run:

C:\cobol\helloworld>cobc -x helloW.cob

C:\cobol\helloworld>helloW
Hello, world!

 

Posted in c-gnuCOBOL | Tagged , | Leave a comment

Portable Air Conditioner Adapter for Casement Window

I’ve lived in this house for many years and every summer, for about a month, the bedroom is just too hot to sleep in until well past bed time. Though I have central A/C, the ducting was designed for heat only and the central A/C has never been very effective upstairs.

The bedroom has just 2 skinny casement windows. I’ve looked at skinny A/C units, but none of them are skinny enough. I’ve looked at portable A/C units, but I could never come up with an acceptable venting option.

This spring I saw portable A/C units for sale at Costco and the question came up again. This time I put the right search criteria into DuckDuckGo and found a guy that had cut a piece of plexiglass the size of his screen. He then cut a hole in the plexiglass to allow for the vent:

Genius! I had been trying to work out a way to build a wedge-shaped device that the window could close down on.

After going thru various reviews, I ended up purchasing this Black & Decker model BPACT08WT. The price was right, it would cool my bedroom, and it wasn’t overkill (I don’t like stressing the wiring of this 80 year old house).

Coming up with a flange to connect the hose to the wood screen adapter was another challenge. The black and decker A/C unit uses a 5″ hose, so I ordered two difference 5″ flanges and hose clamps on amazon. When they showed up I found the flanges were exactly 5″ as well. There was no way to get the hose over the flange short of cutting it and I just didn’t like that idea.

After more research I found this flange on Amazon:

At $27.99, way more expensive than the other flanges but this offer louvers plus threads to mate to the tubing. When the flange showed up it fit properly so I was ready to begin building the full adapter. Interestingly, the flange is 3D printed.

Using the screen as a template, I cut the proper size out of a half sheet of 1/4″ plywood. Using a compass and some of the scrap, I test cut a 5.5″ hole with a jig saw and a fine blade. The flange fit properly, and  I was confident I could cut a fairly round hole in the actual project.

Once the wood was cut, the edges smoothed with a router’s 1/8″ round-over bit, and everything sanded, I primed and painted it with matching semi-gloss paint.

For final assembly, I cut out a bit of screen I had laying around and found 3 nylon bolts to fasten the flange to the wood.

The white rectangle right of the bolts is paraffin. I rubbed that onto the flange where it would come in contact with the wood. I also rubbed it around the perimeter of the finished wood. This will prevent the paint from sticking to the flange or the old woodwork in the window.

Here is the finished adapter ready to be installed:

Here is the final install:

Posted in c-Misc | Tagged , | Leave a comment

Installing MinGW (for gnuCOBOL)

As I started researching how to install the gnuCOBOL SQL preprocessor, I found that there are no binaries (Windows or Linux). If I’m going to move forward, I’m going to have to be able to  compile the preprocessor.

One option is to take a step backwards and redo what I’ve done so far on Linux. But for no particularly good reason, I want to do this project on Windows. That means getting gcc running under Windows. Cue minGW.

For what seems like 20 years, I’ve been using unxutils to provide Unix based commands in Windows which allows me to move between Windows and Linux seamlessly. BUT unxutils just provides some basic utilities, it doesn’t provide the ability to compile and run C programs on Windows.

One option is the new Windows Subsystem for Linux (WSL). I have multiple issues with this – it requires Windows 10 64bit, is a full blown Linux install, and it is Microsoft. I’m looking for simple, small, and clean. That is not typical of Microsoft. OK, I have an attitude.

The other options are MinGW or cygwin. gnuCOBOL for Windows is compiled on MinGW and the preprocessor seems to have no preference, so I will install MinGW and see how it goes.

The plus side to MinGW is it will replace my old unxutils and provide the same features plus provide bash on top of Windows.

MinGW Installation

Considering the general complexity of what is being installed, the installation is amazingly simple. You download an installer which works much like the Linux Synaptic Manager. From there you select which parts of MinGW you want to install.

The installer is found at https://sourceforge.net/projects/mingw/files/Installer/

Once started, I selected the default options (installing into c:\MinGW). Once the installer is setup, it asks which parts of MinGW you want to install. I selected mingw32-base (gcc), and msys-base (bash + utilities):

Before attempting to run anything, edit the file C:\MinGW\msys\1.0\etc\fstab. It
must contain:

# Win32_Path                           Mount_Point
#------------------------------------- -----------
C:/MinGW                               /mingw
C:/                                    /c

C:/ is important because it allows bash access to the entire hard drive, otherwise you will only have access to the c:\mingw\msys\1.0 directory.

Next, in C:\MinGW\msys\1.0, copy a link of msys.bat to Start Menu, named bash, so bash can be run from the start menu.

At this point, you can double click on the msys.bat (bash) link and bash will start.

Finally, add c:\mingw\msys\1.0\bin to your path. When done, commands such as ls can be run from cmd.

Installing Other Packages

There are some other packages that I know I would want. These can be installed directly using mingw-get:

mingw-get install msys-vim
mingw-get install msys-wget

Some Operational Notes

You can start bash from inside cmd like this:

bash -l

-l means to run login scripts.

To run a script with bash, you run bash and specify the path as you would inside bash. For example, if I want to run c:\tmp\test.sh, use:

bash -l -c /c/tmp/test.sh

You may or may not want -l. I have an extensive login script that I always want run.

Using scp (or pscp) requires a slightly screwy path as well.

scp myfile /tmp

will work fine.

scp myfile myhost:/tmp

will fail with ssh: Could not resolve hostname myhost;c: No such host is known.

I don’t fully understand what is going on, but myhost:/tmp is not being translated correctly. To get it to work you need two //:

scp myfile myhost://tmp

I have found that I can copy the entire MinGW environment between machines by simply copying c:\MinGW and adding the path.

Conclusion

I’m looking forward to further experiments with MinGW. I don’t have to write many cmd BAT files any more but when I do I just detest them. They are so clunky compared to bash. I would be perfectly happy migrating everything to bash.

Posted in c-gnuCOBOL | Tagged , | 1 Comment

Installing PostgreSQL (for GnuCOBOL)

I recently wrapped up a couple of mainframe COBOL/DB2 classes at udemy.com. In general, these were refresher courses in COBOL, but I did find the EXEC SQL pre-processor very interesting.

I left the COBOL world before SQL was mainstream. When we used the computer database management system (DBMS), it was via calls like one would still do in most modern computer languages such as

CALL "DBGET" USING DBNAME, TABLENAME, ....

Once SQL came along some COBOLs (as far as I can recall HP’s COBOL/3000 was given this ability), there was a pre-processor (EXEC SQL) that allowed you to code SQL directly into COBOL such as

DISPLAY "ENTER USER-ID:".
ACCEPT USER-ID.

EXEC SQL
    SELECT USERNAME INTO :USER-NAME 
      FROM USERTABLE WHERE USERID = :USER-ID
END-EXEC.

IF SQLCODE NOT = 0, 
    DISPLAY "USER ID WAS NOT FOUND".

The mainframe COBOL/DB2 uses this pre-processor. Since there is no practical way for me to code on a mainframe (the service I looked into wanted over $300 / mo), I thought it would be neat to see if I could get a pre-processor running on gnuCOBOL. Turns out someone has written just such a pre-processor.

Getting the pre-processor running is a future topic, but one of the requirements is PostgreSQL – that is the DBMS it interfaces with.

So this blog post is my notes for getting PostgreSQL up and running.

PostgreSQL, mySQL, and SQLite

It has been years now since I used mySQL, but I did once heavily use it. I wrote an application that handled netflow data from a couple hundred routers. At the time I was pretty impressed that I was processing roughly 5 million records a day in mySQL. I liked mySQL but my knowledge of it is now 10 years out of date (jeez, how can that be??).

In my own projects for the past several years I selected SQLite as my DBMS software. I liked the licensing, and I was OK with the fact that cannot allow networked access. Plus it is very lightweight.

I believe I had looked at Postgres (as it was then called) when I looked at mySQL and mySQL looked like a much better solution then.

So how does PostgresSQL compare to mySQL and SQLite?

This article is a pretty quick comparison of the differences between the three:

https://www.digitalocean.com/community/tutorials/sqlite-vs-mysql-vs-postgresql-a-comparison-of-relational-database-management-systems

A super high-level summary:

SQLite is good for IOT, or where an embedded database is necessary (my situation). It is not good for large volumes or networked access.

mySQL is popular, easy to use, and provides fast reads. Great for websites. Downside is Oracle hasn’t been keeping it current.

postgreSQL is better at data integrity and complex operations. Downside is a more complex product.

Installing PostgreSQL

While researching PostgreSQL I found this tutorial site which I found very useful for quickly getting the DBMS installed, running, setting up some test tables, and experimenting with the DBMS:

PostgreSQL Tutorial

Here are the highlights of installation:

  • The installation procedure found in PostgreSQL Tutorial starts at

https://www.postgresqltutorial.com/install-postgresql/

  • Download the Installer.

Installers are found at

https://www.enterprisedb.com/downloads/postgres-postgresql-downloads

I’m installing onto a test Windows box. So I selected the latest and greatest PostgreSQL version.

  • Run the Installer.

Answered a few questions and 10 minutes later PostgreSQL was installed. I looked at stack builder (end of installation), but there were no other optional packages I could see using at the moment.

  • Once the PostgreSQL server is running, I started pgadmin4 (in start menu) to poke around. Although browser based, this is a very nice built in query tool.

Installing Test Data

The tutorial site includes test data of a fictional DVD rental store. It includes many tables, fields, and relationships to experiment with. Besides providing example data for their tutorial, it will provide me example data down the road for gnuCOBOL.

The instructions for downloading the DVD Rental Store database is found at

https://www.postgresqltutorial.com/postgresql-sample-database/

The procedure for uploading the data into the service is at

https://www.postgresqltutorial.com/load-postgresql-sample-database/

Once the data is loaded, I used pgadmin4 to verify the tables and data exist:

Following Along with the Tutorial

At this point, you have the necessary data installed to do the PostgreSQL tutorial. I did so just to get a feeling for this DBMS.

Compared to SQLite which I know well and my fading memory of mySQL of 10 years ago, this is an amazing product. It was easy to get running and use.

Installing a Different SQL Query Tool

pgadmin4 is much nicer than the tools that come with SQLite (and what I recall coming with mySQL long ago), but I’m not a big fan of web-based software. So I went looking for a different query tool.

I ended up settling on DBeaver. It is free, has lots of features, and also works with mySQL and SQLite so it could possibly become my de facto SQL tool. In my, so far, limited use of it, I like it though it has been really slow to start up.

You can find DBeaver here

https://dbeaver.io/download/

Here is an example of output:

Conclusion

I now have a working DBMS to use with gnuCOBOL.

Posted in c-gnuCOBOL | Tagged , | 2 Comments

The Ultimate Electronics Toolbox

In the early 80’s I stumbled across a Plano 757 tackle box and purchased it to store my small assortment of electronic tools and parts. It quickly ended up at my office where I was constantly having to make cable ends for RS-232 equipment or crimp RJ-11 and RJ45 connectors for LAN patch cords.

In my opinion, it is the best electronics toolbox I’ve ever seen. The compartment layout allows for lots of little parts and some fairly long tools. I could even keep small wire cutters and needle nose pliers in the trays. On top is plenty of room for big equipment where I kept the crimpers and multimeters.

Tackle boxes generally have a bunch of trays that open when you lift the lid, or they have plastic boxes that slide in. You have to remove the box, then open the lid. This one you just slide open drawers to gain access. I loved it.

After purchasing this box, I really wanted another but either Plano stopped making them or they were very hard to come by. In the late 90’s (nearly 15 years later), I stumbled across a clearly old ‘new’ one at a mom&pop sporting goods store. I snapped it up and that became my home toolbox.

After I retired, the work toolbox became my primary toolbox and the newer one contains everything I need to go onsite and work on telephone or CATV wiring. Here is the 1980’s model still going strong:

Never saw one again until today (20+ years later). Today I was going thru amazon looking for a small tackle box for first aid supplies and I stumbled across a model 757-004 (I’m guessing revision #4). Here is the Amazon Link.

It is hard to tell if the drawer layout is the same. I tried to locate other pictures of the drawers, but this is the only picture anyone shows in their ad. My version’s lowest drawer has some bigger bins for small tools. This new box also has some bins on top of the lid.

Toolboxes, like work benches, are pretty specific to your own taste, but if you are looking around for an electronics toolbox, I’d say this one is worth a look.

 

Posted in c-electronics | Tagged , | Leave a comment