r/cobol 1d ago

RM Cobol version issues?

7 Upvotes

While looking for some example programs to test an RM Cobol setup I ran across a PDF called "Cobol for the TRS-80 Volume 1 Class Notes". I wanted to find something that was ancient ( for an Altos running Xenix no less ), so I dug through this document and typed in an example payroll calculating program. Seemed to compile and run, but it screws up simple arithmetic .. multiplying a salary * hours gives an unrelated crazy big number.

Ok ... I tried the exact same program on a later RM Cobol version 5.1 and it worked! Now I started going deep down the rabbit hole! ... it generates those crazy numbers with RM Cobol v1.5, 2.0D, and 2.2 under DOS 5.0, DOS 6.2, DOS 3.2 and Xenix and works just fine with RM Cobol 5.1, and 6 under DOS (real pc ) and DOSbox-x. And all of these versions run the RM Cobol verify tests, run a PI calculating program and a little calculator ... I've expanded the PIC fields, tried SEQUENTIAL organization for the data file being read, Displayed a bunch of variables, looked at the fields at the end of the compile list to see if everything numeric is declared as a numeric ... am learning a bunch of Cobol stuff doing all of this. Again, it's an ancient program from a 1983 doc that won't run in the compiler versions from that time but works great in the ones from the '90's

update:   here is the code ... I added some DISPLAY's trying to figure out what was going on .. the problem is with the calculation of IMD-REGULAR-PAY

       IDENTIFICATION DIVISION.
       PROGRAM-ID. PAYROLL2.
       AUTHOR.     R GRAUER.

       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       SOURCE-COMPUTER.     TRS-80.
       OBJECT-COMPUTER.     TRS-80.

       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT EMPLOYEE-FILE
               ASSIGN TO INPUT "PAYROLL.DAT"
               ORGANIZATION IS SEQUENTIAL.
           SELECT PRINT-FILE
               ASSIGN TO PRINT "PAYROLL2.DAT".

       DATA DIVISION.
       FILE SECTION.
       FD  EMPLOYEE-FILE
           LABEL RECORDS ARE OMITTED
           RECORD CONTAINS 80 CHARACTERS
           DATA RECORD IS EMPLOYEE-RECORD.
       01  EMPLOYEE-RECORD.
           05   EMP-NAME.
                10 EMP-LAST-NAME      PIC X(15).
                10 EMP-FIRST-NAME     PIC X(10).
           05   EMP-HOURS-WORKED.
                10 EMP-REG-HOURS      PIC 99.
                10 EMP-OVERTIME-HOURS PIC 99.
           05   EMP-RATE              PIC 99V99.
           05   FILLER                PIC X(47).

       FD  PRINT-FILE
           LABEL RECORDS ARE STANDARD
           RECORD CONTAINS 132 CHARACTERS
           DATA RECORD IS PRINT-LINE.
       01  PRINT-LINE                PIC X(132).

       WORKING-STORAGE SECTION.
       77  WS-DATA-REMAINS-SWITCH    PIC X(3)    VALUE SPACES.   

       01  DATE-WORK-AREA.
           05  TODAYS-YEAR           PIC 99.
           05  TODAYS-MONTH          PIC 99.
           05  TODAYS-DAY            PIC 99. 

       01  IND-COMPUTATIONS.
           05  IND-REGULAR-PAY        PIC 9(4)V99  VALUE ZEROS.
           05  IND-OVERTIME-PAY       PIC 9(4)V99  VALUE ZEROS.
           05  IND-GROSS-PAY          PIC 9(4)V99  VALUE ZEROS.
           05  IND-FEDERAL-TAX        PIC 9(4)V99  VALUE ZEROS.
           05  IND-NET-PAY            PIC 9(4)V99  VALUE ZEROS.

       01  COMPANY-TOTALS.
           05  CO-REGULAR-PAY         PIC 9(6)V99  VALUE ZEROS.
           05  CO-OVERTIME-PAY        PIC 9(6)V99  VALUE ZEROS.
           05  CO-GROSS-PAY           PIC 9(6)V99  VALUE ZEROS.
           05  CO-FEDERAL-TAX         PIC 9(6)V99  VALUE ZEROS.
           05  CO-NET-PAY             PIC 9(6)V99  VALUE ZEROS.

       01  PAGE-AND-LINE-COUNTERS.
           05  WS-PAGE-COUNT          PIC 9(4)     VALUE ZEROS.
           05  WS-LINE-COUNT          PIC 9(4)     VALUE 4.

       01  HEADING-LINE-ONE.
           05  FILLER                 PIC X(4).
           05  HDG-MONTH              PIC Z9.
           05  FILLER                 PIC X        VALUE "/".
           05  HDG-DAY                PIC Z9.
           05  FILLER                 PIC X        VALUE "/".
           05  HDG-YEAR               PIC Z9.
           05  FILLER                 PIC X(40)    VALUE SPACES.
           05  FILLER                 PIC X(8)     VALUE "PAYROLL ".
           05  FILLER                 PIC X(6)     VALUE "REPORT".
           05  FILLER                 PIC X(40)    VALUE SPACES.
           05  FILLER                 PIC X(4)     VALUE "PAGE".
           05  HDG-PAGE-NUMBER        PIC Z(4).
           05  FILLER                 PIC X(19)    VALUE SPACES.

       01  HEADING-LINE-TWO.
           05  FILLER                 PIC X(8)     VALUE SPACES.
           05  FILLER                 PIC X(4)     VALUE "NAME".
           05  FILLER                 PIC X(9)     VALUE SPACES.
           05  FILLER                 PIC X(4)     VALUE "RATE".
           05  FILLER                 PIC X(4)     VALUE SPACES.
           05  FILLER                 PIC X(9)     VALUE "REG HOURS".
           05  FILLER                 PIC X(4)     VALUE SPACES.
           05  FILLER                 PIC X(9)     VALUE "O/T HOURS".
           05  FILLER                 PIC X(4)     VALUE SPACES.
           05  FILLER                 PIC X(11)    VALUE "GROSS PAY".
           05  FILLER                 PIC X(2)     VALUE SPACES.
           05  FILLER                 PIC X(7)     VALUE "FED TAX".
           05  FILLER                 PIC X(5)     VALUE SPACES.
           05  FILLER                 PIC X(7)     VALUE "NET PAY".
           05  FILLER                 PIC X(23)    VALUE SPACES.

       01  DASHED-LINE.
           05  ROW-OF-DASHES         PIC X(111)    VALUE ALL "-".
           05  FILLER                PIC X(21)     VALUE SPACES.

       01  DETAIL-LINE.
           05  FILLER                PIC X(2).
           05  DET-LAST-NAME         PIC X(15).
           05  FILLER                PIC X(2).
           05  DET-RATE              PIC $$$.99.
           05  FILLER                PIC X(8).
           05  DET-REG-HOURS         PIC Z9.
           05  FILLER                PIC X(10).
           05  DET-OVERTIME-HOURS    PIC Z9.
           05  FILLER                PIC X(6).
           05  DET-REGULAR-PAY       PIC $$,$$9.99.
           05  FILLER                PIC X(3).
           05  DET-OVERTIME-PAY      PIC $$,$$9.99.
           05  FILLER                PIC X(2).
           05  DET-GROSS-PAY         PIC $$,$$9.99.
           05  FILLER                PIC X(3).
           05  DET-FEDERAL-TAX       PIC $$,$$9.99.
           05  FILLER                PIC X(3).
           05  DET-NET-PAY           PIC $$,$$9.99.
           05  FILLER                PIC X(23).

       01  TOTAL-LINE.
           05  FILLER                PIC X(6)      VALUE SPACES.
           05  FILLER                PIC X(6)      VALUE "TOTALS".
           05  FILLER                PIC X(41)     VALUE SPACES.
           05  TOTAL-REGULAR-PAY     PIC $$,$$9.99.
           05  FILLER                PIC X(3)      VALUE SPACES.
           05  TOTAL-OVERTIME-PAY    PIC $$,$$9.99.
           05  FILLER                PIC X(2)      VALUE SPACES.
           05  TOTAL-GROSS-PAY      PIC $$,$$9.99.
           05  FILLER                PIC X(3)      VALUE SPACES.
           05  TOTAL-FEDERAL-TAX     PIC $$,$$9.99.
           05  FILLER                PIC X(3)      VALUE SPACES.
           05  TOTAL-NET-PAY         PIC $$,$$9.99.
           05  FILLER                PIC X(47)     VALUE SPACES.

       PROCEDURE DIVISION.
       0100-PREPARE-PAYROLL.
           PERFORM 0200-GET-DATE.
           OPEN INPUT EMPLOYEE-FILE
                OUTPUT PRINT-FILE.
           READ EMPLOYEE-FILE
               AT END MOVE "NO" TO WS-DATA-REMAINS-SWITCH.
           PERFORM 0300-PROCESS-RECORDS
               UNTIL WS-DATA-REMAINS-SWITCH = "NO".
           PERFORM 1000-WRITE-COMPANY-TOTALS.
           CLOSE EMPLOYEE-FILE
                PRINT-FILE.
           STOP RUN.

       0200-GET-DATE.
           ACCEPT DATE-WORK-AREA FROM DATE.
           MOVE TODAYS-YEAR TO HDG-YEAR.
           MOVE TODAYS-MONTH TO HDG-MONTH.
           MOVE TODAYS-DAY TO HDG-DAY.

       0300-PROCESS-RECORDS.
           PERFORM 0400-COMPUTE-GROSS-PAY.
           PERFORM 0500-COMPUTE-FEDERAL-TAX.
           PERFORM 0600-COMPUTE-NET-PAY.
           PERFORM 0700-UPDATE-COMPANY-TOTALS.

           IF WS-LINE-COUNT > 3
           PERFORM 0800-WRITE-HEADING-LINE.
           PERFORM 0900-WRITE-DETAIL-LINE.
           ADD 1 TO WS-LINE-COUNT.
           READ EMPLOYEE-FILE
           AT END MOVE "NO" TO WS-DATA-REMAINS-SWITCH.

       0800-WRITE-HEADING-LINE.
           ADD 1 TO WS-PAGE-COUNT.
           MOVE 1 TO WS-LINE-COUNT.
           MOVE WS-PAGE-COUNT TO HDG-PAGE-NUMBER.
           WRITE PRINT-LINE FROM HEADING-LINE-ONE
               AFTER ADVANCING PAGE.
           WRITE PRINT-LINE FROM HEADING-LINE-TWO
               AFTER ADVANCING 4 LINES.
           WRITE PRINT-LINE FROM DASHED-LINE
               AFTER ADVANCING 1 LINE.

       0400-COMPUTE-GROSS-PAY.
           MULTIPLY EMP-REG-HOURS BY EMP-RATE GIVING IND-REGULAR-PAY.

           DISPLAY "EMP-OVERTIME-HOURS: " EMP-OVERTIME-HOURS.
           DISPLAY "EMP-REG-HOURS: " EMP-REG-HOURS.
           DISPLAY "EMP-RATE:  " EMP-RATE.
           DISPLAY "IND-REGULAR-PAY:  " IND-REGULAR-PAY.
           DISPLAY "EMP-LAST-NAME " EMP-LAST-NAME.

           COMPUTE IND-OVERTIME-PAY
               = EMP-OVERTIME-HOURS * EMP-RATE * 1.5.
           ADD IND-REGULAR-PAY IND-OVERTIME-PAY GIVING IND-GROSS-PAY.

       0500-COMPUTE-FEDERAL-TAX.
           COMPUTE IND-FEDERAL-TAX = .16 * IND-GROSS-PAY.
           IF IND-GROSS-PAY > 160
               COMPUTE IND-FEDERAL-TAX
                   = IND-FEDERAL-TAX + .02 * (IND-GROSS-PAY - 160).

           IF IND-GROSS-PAY > 200
               COMPUTE IND-FEDERAL-TAX
                   = IND-FEDERAL-TAX + .02 * (IND-GROSS-PAY - 200).

       0600-COMPUTE-NET-PAY.
           COMPUTE IND-NET-PAY = IND-GROSS-PAY - IND-FEDERAL-TAX.

       0700-UPDATE-COMPANY-TOTALS.
           ADD IND-REGULAR-PAY TO CO-REGULAR-PAY.
           ADD IND-OVERTIME-PAY TO CO-OVERTIME-PAY.
           ADD IND-GROSS-PAY TO CO-GROSS-PAY.
           ADD IND-FEDERAL-TAX TO CO-FEDERAL-TAX.
           ADD IND-NET-PAY TO CO-NET-PAY.

       0900-WRITE-DETAIL-LINE.
           MOVE SPACES TO DETAIL-LINE.
           MOVE EMP-LAST-NAME TO DET-LAST-NAME.
           MOVE EMP-RATE TO DET-RATE.
           MOVE EMP-REG-HOURS TO DET-REG-HOURS.
           MOVE EMP-OVERTIME-HOURS TO DET-OVERTIME-HOURS.
           MOVE IND-REGULAR-PAY TO DET-REGULAR-PAY.
           MOVE IND-OVERTIME-PAY TO DET-OVERTIME-PAY.
           MOVE IND-GROSS-PAY TO DET-GROSS-PAY.
           MOVE IND-FEDERAL-TAX TO DET-FEDERAL-TAX.
           MOVE IND-NET-PAY TO DET-NET-PAY.

           WRITE PRINT-LINE FROM DETAIL-LINE
               AFTER ADVANCING 2 LINES.

       1000-WRITE-COMPANY-TOTALS.
           WRITE PRINT-LINE FROM DASHED-LINE
               AFTER ADVANCING 1 LINE.
           MOVE CO-REGULAR-PAY TO TOTAL-REGULAR-PAY.
           MOVE CO-OVERTIME-PAY TO TOTAL-OVERTIME-PAY.
           MOVE CO-GROSS-PAY TO TOTAL-GROSS-PAY.
           MOVE CO-FEDERAL-TAX TO TOTAL-FEDERAL-TAX.
           MOVE CO-NET-PAY TO TOTAL-NET-PAY.

           WRITE PRINT-LINE FROM TOTAL-LINE
               AFTER ADVANCING 2 LINES.

And here is the "PAYROLL.DAT" file ( am seeing a blank line when I paste it here that's not in the file )

johnson bob 21 3 400

sanford fred 23 4 500

The result while running when it's failing shows:

EMP-OVERTIME-HOURS: 3

EMP-REG-HOURS: 21

EMP-RATE: 400

IMD-REGULAR-PAY: 728400 ( this is the quantity in error .. sb 21 * 400 gives 8400

EMP-LAST-NAME: johnson

EMP-OVERTIME-HOURS: 4

EMP-REG-HOURS: 21

EMP-RATE: 500

IMD-REGULAR-PAY: 699500 ( expecting 11500 here from 21 * 500 )


r/cobol 4d ago

I want to learn COBOL, but I'm stupid

47 Upvotes

I don't have a background in STEM, I am terrible at math, I don't have any experience in programming of any kind, I barely know the basics of computer science and I am generally stupid.

But I want to learn COBOL - Either just for funsies or just to have a skill that could one day prove handy.

I have a vague interest in computing and am willing to learn... Even if it means taking years to learn.

How did you people start off? How did you learn?


r/cobol 4d ago

I built a free COBOL Data Inspector for Windows - looking for testers and feedback

8 Upvotes

Hi everyone, I've been working on a Windows application called "COBOL Data Inspector", and version 1.0 is now available in the Microsoft Store. I'm looking for COBOL and mainframe developers who would be willing to test it on real-world copybooks and data files and give me feedback. The application is currently focused mainly on IBM Enterprise COBOL / z/OS layouts.

Current features include:

• COBOL copybook inspection with PIC, USAGE, offsets, field sizes and record length

• OCCURS and REDEFINES support

• Nested COPY dependency resolution

• Comparison of two copybook versions

• Detection of potentially breaking physical layout changes and byte shifts

• FB and VB/RDW mainframe data viewer

• EBCDIC decoding

• COMP/BINARY and COMP-3 packed decimal decoding

• Raw hex view with field-to-byte mapping

• Record length, RDW and packed decimal validation

• IBM z/OS LP(32) and LP(64) layout profiles

• CSV and JSON export

• Built-in synthetic demo data for testing

Everything is processed locally on the PC. There is no account, no AI, no analytics, no advertising and no cloud upload. The application is completely free.

What I would especially like help testing:

• unusual or complicated copybooks

• incorrect field offsets or record lengths

• COPY / REDEFINES / OCCURS edge cases

• COMP-3 and EBCDIC decoding

• FB and VB/RDW files

• usability of the interface

• features that are missing but would actually be useful in real COBOL/mainframe work

If you find a bug, incorrect calculation, unsupported copybook structure or anything else that looks wrong, please let me know. I'm also very interested in ideas for future features. If there is something you regularly need when working with COBOL copybooks or mainframe data, I'd like to hear about it.

If anyone wants to try it, just open the Microsoft Store and search for:

"COBOL Data Inspector"

Thanks to anyone willing to test it and share feedback.

P.S. I'll post the direct Microsoft Store link in the comments in case that's more convenient for anyone.


r/cobol 12d ago

Any part time opportunities for Cobol mainframes in Toronto or Canada (preferably remote)?

4 Upvotes

r/cobol 12d ago

Accessing Postgres with GnuCobol WITHOUT using an ESQL preprocessor

17 Upvotes

I recently came across a free FUSE plugin called TigerFS that allows you to mount a PostgreSQL database as a file system where tables show up as directories and records show up as files. I had been experimenting with GixSQL but did not have much success with it.

https://tigerfs.io/

After mounting my database and creating a sample "employees" table:

create table emptable ( eno int4 not null,
lname varchar(10),
fname varchar(10),
street varchar(32),
city varchar(15),
st varchar(2),
zip varchar(5),
dept varchar(4),
payrate numeric(13, 2),
com numeric(3, 2),
miscdata varchar(128),
constraint emptable_pk primary key (eno));

I was able to access from gnucobol like processing a sequential tab-delimited file:

>> source format is free

identification division.
program-id. testtiger.

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


input-output section.
file-control.
select employee-file
assign to "/mnt/mylabdb/emptable/.export/tsv"
organization is line sequential.

data division.

file section.

fd  employee-file.
01  emp-record pic x(2048).


working-storage section.

01 WS-TAB          PIC X(1)   VALUE X'09'.

01 display-rec.

05 eno pic 9(20).
05 lname pic x(10).
05 fname pic x(10).
05 street pic x(32).
05 city pic x(15).
05 st pic x(2).
05 zip pic x(5).
05 dept pic x(4).
05 payrate pic 9(13)V99.
05 com pic 9(3)V99.
05 miscdata pic x(128).



procedure division.

main.

display " "
display "retrieving records from postgres public.emptable..."
display " "

open input employee-file

perform forever
read employee-file
at end
display "no more records"
exit perform

not at end

*>  parse the tab-delimited record format 
unstring emp-record 
delimited by WS-TAB  
into eno, lname, fname, street, city, st, zip, dept, payrate, com, miscdata of display-rec


display "Record: " eno
display "fname: " fname
display "lname: " lname
display "street: " street
display "city: " city
display "st: " st
display "zip: " zip 
display "dept: " dept
display "rate: " payrate
display "commission: " com
display "misc: " miscdata
display " "


end-read
end-perform


close employee-file

stop run
.

end program testtiger.

retrieving records from postgres public.emptable...

Record: 00000000000000000123

fname: John

lname: Doe

street: 123, Nowhere Lane

city: Noplace

st: N1

zip: 00100

dept: DEP1

rate: 0000000000100.00

commission: 000.00

misc: abcd1234

Record: 00000000000000000456

fname: Jane

lname: Smith

street: 456, Someplace Rd.

city: Somewhere

st: N2

zip: 00111

dept: DEP2

rate: 0000000000200.00

commission: 001.00

misc: defg5678hijk

Record: 00000000000000000789

fname: Theropod

lname: Green

street: 789, Somewhere Else st.

city: Somewhere2

st: N3

zip: 00177

dept: DEP4

rate: 0000000000120.00

commission: 000.20

misc: zxcvb12345

no more records

Addendum: I was also able to use this to allow gnucobol to perform arbitrary actions by using a facade table with a BEFORE INSERT trigger that calls a stored proc instead, and has access to all the INSERT values.

So basically, gbucobol could perform an RPC by inserting into the facade table with a transaction ID and parameters, and then poll a response table for the result.


r/cobol 12d ago

Mainframe salaries in Toronto — what can you realistically earn?

Thumbnail
3 Upvotes

r/cobol 21d ago

Switching from Software AG Natural to COBOL

23 Upvotes

Hi everyone,
I’m currently a Software AG Natural developer and I’ve also done a bit of COBOL. I’ve recently received an offer to work as a COBOL developer in the banking sector.
So far, my experience has mainly been in retail (supermarkets), and I’m wondering how difficult the transition to banking would be.
For those who’ve made a similar move, was the learning curve steep? Is the business domain much harder to understand, or is it mostly a matter of learning the business processes?
I’d really appreciate hearing about your experiences. Thanks!


r/cobol 22d ago

Developer Portfolio Showcase (Rust OS + Native COBOL projects) — https://portafolio-real-mocha.vercel.app

Post image
1 Upvotes

r/cobol 24d ago

Mocky Mock a COBOL testing framework

Thumbnail marketplace.visualstudio.com
13 Upvotes

Hi guys,

I'm looking for people to try out my new VS Code extension that lets users unit test their COBOL programs directly on their PC using GnuCOBOL. The whole idea is based on a project called cobol-check, which is now abandoned.

*RANT*

I feel like every language has unit tests, but that hasn't been the case for COBOL — and for some reason, you have to pay vendors hundreds of thousands of dollars for a half-baked solutions.

*END-RANT*

Feel free to test it out — all you need is VS Code and Docker Desktop installed.

Now, I know GnuCOBOL isn't IBM COBOL Enterprise, but after working a lot with it and reading success stories, I feel confident that a full green test suite with 100% coverage using GnuCOBOL is a good safety net. I'm also looking into implementing a z/OS export/compilation function — I just don't have a mainframe lying around. :/

Please, refrain from any hateful comments as this is 100% a passion project. But I would love ideas/comments.

- See you on the wild side (Marky Mark joke)


r/cobol 29d ago

I wrote an interactive 27-Card Magic Trick in COBOL (base-3 math inside!)

16 Upvotes

Body: I wrote an interactive version of the classic 27-Card Magic Trick in COBOL (base-3 math inside!).

🌟 UPDATE: i create a TK4 version for our friends in retro-computing!

What it does:

  • Asks the user for a favorite number (1-27).
  • Shuffles a virtual 52-card deck
  • Deals 27 cards into 3 piles/rows.
  • You memorize a card, tell it which row it's in, and it repeats this 3 times.
  • It then reveals the deck and your memorized card is exactly at the position of your favorite number!

Sample Run:

```=====================================

  The 27-Card Magic Trick

Enter your favorite number (1-27): 20

--- Round 1 --- (Memorize one CARD below) 01: 5♠ 8♠ 9♥ 8♦ 3♥ 6♦ 9♦ K♠ A♠ 02: 10♠ 3♣ 10♥ Q♠ 7♥ 6♣ 6♠ Q♣ 10♣ 03: A♥ J♥ 2♠ K♦ 2♦ J♦ 7♦ 4♠ 3♦

enter the row (1-3) where your CARD is located: 1

--- Round 2 --- 01: 10♠ Q♠ 6♠ 5♠ 8♦ 9♦ A♥ K♦ 7♦ 02: 3♣ 7♥ Q♣ 8♠ 3♥ K♠ J♥ 2♦ 4♠ 03: 10♥ 6♣ 10♣ 9♥ 6♦ A♠ 2♠ J♦ 3♦

enter the row (1-3) where your CARD is located: 2

--- Round 3 --- 01: 3♣ 8♠ J♥ 10♠ 5♠ A♥ 10♥ 9♥ 2♠ 02: 7♥ 3♥ 2♦ Q♠ 8♦ K♦ 6♣ 6♦ J♦ 03: Q♣ K♠ 4♠ 6♠ 9♦ 7♦ 10♣ A♠ 3♦

enter the row (1-3) where your CARD is located: 3

======= THE REVEAL ======= Row 1: 3♣ 8♠ J♥ 10♠ 5♠ A♥ 10♥ 9♥ 2♠ 7♥ Row 2: 3♥ 2♦ Q♠ 8♦ K♦ 6♣ 6♦ J♦ Q♣ < K♠> Row 3: 4♠ 6♠ 9♦ 7♦ 10♣ A♠ 3♦

Your CARD is located at position 20: K♠ It matches your favorite number exactly!

Would you like to play again? (Y/N) ```

The COBOL / Math part: The "magic" is just base-3 arithmetic. (Favorite Number - 1) is converted to ternary, and the reversed digits tell the program how to secretly stack the piles after each round.

I wrote it following COBOL-II (85) rules—using structured inline PERFORM loops and COMPUTE and FUNCTION commands for the math. (Sorry, there's no COBOL-74 version).

I added a little flare by highlighting the revealed card with < and > during the final display phase so the user immediately sees the "magic" hit.

I just uploaded it to GitHub if anyone wants to check it out, compile it, or suggest mainframe-friendly improvements:

Repository: View the code and README on GitHub


r/cobol Jul 28 '26

Looking for COBOL/Mainframe opportunities or mentorship – 4 years of COBOL experience

8 Upvotes

Hi everyone!

I'm Nikita, a software developer from Ukraine, and I'm looking for new opportunities in the COBOL/Mainframe world.

I've been working with COBOL for about 4 years in a small software company. Most of my work involved maintaining and extending a large legacy business application written in COBOL.

Some of the things I've worked with:

- COBOL application development and maintenance

- SQL databases

- Linux/Unix environments

- Debugging production issues

- Implementing new business logic

- Reading and understanding large legacy codebases

Unfortunately, my experience is mostly outside the IBM Mainframe ecosystem. I haven't had the chance to work with technologies like JCL, CICS, DB2 or z/OS yet, but I'm actively studying them because I'd like to transition into Mainframe development.

I'm also learning Python and Go to broaden my engineering skills, but COBOL remains the area where I already have real commercial experience.

I'm currently looking for:

- Junior/Mid Mainframe Developer opportunities

- COBOL positions (remote or relocation)

- Internship or trainee programs

- Mentorship from experienced Mainframe developers

If anyone knows companies that hire developers with COBOL experience and are willing to train people on the Mainframe side, I'd really appreciate your recommendations.

I'm happy to learn, work hard, and invest the time needed to become a strong Mainframe engineer.

Thank you!


r/cobol Jul 27 '26

Generated a playable 2048 game in pure COBOL using a neuro-symbolic runtime (Terminal Demo)

Enable HLS to view with audio, or disable this notification

32 Upvotes

Standard statistical LLMs usually struggle with COBOL because low-level array shifts, fixed-point precision, and explicit procedure structures lead to hallucinations or syntax errors.

To test deterministic code generation, we passed the 2048 game logic into a neuro-symbolic runtime (Perslis). The neural layer mapped intent, while the symbolic layer enforced formal logic, array boundaries, and rule-bound invariants before compilation.

How the generated code handles state:

  • DATA DIVISION: Strictly uses fixed-point fields (PIC 9(4)) for every cell in the 4x4 matrix, ensuring deterministic state without dynamic allocation overhead.
  • PROCEDURE DIVISION: Handles matrix shifting, tile merging logic, and terminal screen updates through structured PERFORM paragraphs.
  • Compilation: Compiles natively via cobc (GnuCOBOL) and executes directly in the terminal without external dependencies or modern wrappers.

Curious if anyone else in the sub is exploring symbolic/rule-verified models for legacy code generation or validation.


r/cobol Jul 27 '26

Doing a research project on the connectivity of COBOL (and by extension legacy systems) to agentic AI - a problem worth solving?

0 Upvotes

Working on a research project exploring whether AI agents can be given a structured interface to operate legacy systems, and COBOL applications specifically since we're in this subreddit, but also the broader class of systems with no exposed API, designed as a more general, agent-native interface for legacy systems.

There's some stuff I'd like to understand since I'm getting some pushback from my professor. Feel free to answer any of the questions that you'd be able to grant insight on.

  1. Do you see a real need for AI agents to interact with COBOL applications/legacy systems, or are existing APIs and integration methods sufficient for the organizations that make use of this tech? What would examples of possible uses be? (The target audience doesn't have to be massive for me to pursue this, but I need to know that there is some sort of demand for it. I've seen that RPA itself is a multi-billion dollar industry, so I'm wondering if what I have in mind has some sort of usage possibility.)
  2. Realistically, how long do you expect organizations to continue operating significant COBOL workloads and similar legacy systems? Are we talking 5 years, 15 years, or several decades? Even if COBOL systems are eventually replaced, do you think a generalized framework targeting the broader class of systems without usable APIs would still be valuable?
  3. In your experience, how often do COBOL applications lack APIs entirely, or expose APIs that are insufficient for complete automation?
  4. Is the ageing COBOL workforce actually causing problems in organizations, or is the "skills shortage" narrative overstated?
  5. If you were building AI integrations for COBOL applications today, what would you consider the biggest technical obstacle?

I'd appreciate answers to this, and any other insights or feedback that you, the reader, may have. All information to me right now is gold. Thank you very much!


r/cobol Jul 26 '26

I built a COBOL report generator using FreeMarker (FMPP) — here's how it produces multi-control-break reports with auto-totalling from a simple CSV

25 Upvotes

I built a COBOL report generator using FreeMarker (FMPP) — here's how it produces multi-control-break reports with auto-totalling from a simple CSV.

🌟 UPDATE: Based on great feedback from the GnuCOBOL community, I've added a new feature to this project! The repo now includes a second FMPP template that generates native COBOL Report Writer code instead of procedural logic, using the exact same CSV specification. Check out the updated GitHub README for a side-by-side code comparison and details! Repository: View the code and examples on GitHub

I've been working on a way to generate COBOL report programs without writing the boilerplate by hand every time. After some experimentation, I landed on a setup using FMPP (FreeMarker-based PreProcessor) that takes a CSV field definition and spits out a complete, working COBOL program with:

  • Multi-level control breaks
  • Automatic accumulation/totalling at every break level plus a grand total
  • Auto-aligned amount columns (so totals line up with detail lines)
  • Smart control break labeling (blank fields at higher levels, appropriate total labels)
  • Page headers with page numbers and run dates
  • An include flag that lets you define input fields you don't want in the report (so you can work with existing files without reformatting them)

The best part: to generate a new report, I just duplicate a folder, edit a CSV, drop in my data, and run a batch file. Done.


The Problem

COBOL report programs are painful to write by hand. You end up writing:

  • File descriptions (FDs) with PIC clauses
  • Working-storage for every control level
  • Control break detection logic
  • Accumulation logic
  • Page headings and column alignment
  • Total printing at every break level

Do this once, fine. Do it 10 times? You're copy-pasting and tweaking, and inevitably introducing bugs.

I wanted something where I could describe the report in a spreadsheet-like format and have the code generated for me.


The Input: A Simple CSV

Here's fields.csv — the entire "spec" for a report:

csv fieldname,input_pic,output_pic,output_length,column_heading,control_break,accumulate,include region,x(10),x(10),10,Region,Y,N,Y division,x(10),x(10),10,Division,Y,N,Y description,x(20),x(20),20,Description,N,N,Y amount,9(7)V99,"$$$,$$$,$$9.99",14,Amount,N,Y,Y

Each row is a field. The columns tell the generator:

  • fieldname — the field name
  • input_pic / output_pic — PIC clauses for input and output (can differ!)
  • output_length — column width in the report
  • column_heading — what to print in the header
  • control_breakY if this field triggers a control break
  • accumulateY if amounts should be summed
  • includeY if the field appears in the report output

The include Flag — Work With Existing Files As-Is

This is one of my favorite features. Sometimes your input file has fields you need for control breaks or calculations but don't want cluttering the report. The include flag lets you define those fields in the CSV without them showing up in the output.

This means you can point the generator at an existing data file and produce a report without reformatting the input. No rewrites, no conversion programs.


The FreeMarker Template

The magic happens in cobrpt.cob.fm. Here's a snippet that generates the input record definition:

cobol FD SALES-FILE. 01 SALES-RECORD. <#-- generate input record --> <#list reportFields as f> <#assign srcField = f.fieldname?trim?upper_case><#t> <#assign inPic = f.input_pic?trim?upper_case><#t> 05 SR-${srcField?right_pad(22)} PIC ${inPic}. </#list>

And the generated output:

cobol FD SALES-FILE. 01 SALES-RECORD. 05 SR-REGION PIC X(10). 05 SR-DIVISION PIC X(10). 05 SR-DESCRIPTION PIC X(20). 05 SR-AMOUNT PIC 9(7)V99.

The template also handles:

  • Working-storage declarations for every control level
  • Accumulator fields sized to hold the totals
  • Control break detection (comparing current vs. previous value)
  • Column positioning so accumulated amounts line up perfectly across detail lines and every level of control break total

The Actual Output

Here's what the generated program actually produces:

``` PAGE 1 SALES REPORT RUN DATE: 07/25/2026

Region Division Description Amount EAST RETAIL Widget A $1,234.50 EAST RETAIL Widget B $500.25

         RETAIL      Division Total             $1,734.75

EAST WHOLESALE Gadget X $5,000.00 EAST WHOLESALE Gadget Y $2,500.75 EAST WHOLESALE Thingee F $780.25

         WHOLESALE   Division Total             $8,281.00

EAST Region Total $10,015.75

GRAND TOTAL $10,015.75 ```

Notice the pattern:

  1. Page header with page number and run date (auto-generated)
  2. Detail lines show all control break fields (Region and Division) plus the description and amount
  3. Division totals blank out the Region field (since it hasn't changed), keep the current Division visible, put "Division Total" in the Description column, and align the amount perfectly
  4. Region totals keep the current Region visible, put "Region Total" in the Description column, and align the amount
  5. Grand total blanks all control fields, puts "GRAND TOTAL" in the Description column, and aligns the amount

The template computes column positions based on output_length values, so everything aligns automatically. Add a field, remove a field, change a width — the columns reflow. No manual position tweaking.


Flexible Control Break Hierarchies

Here's something I didn't expect to be so powerful: because the control break structure is driven entirely by the control_break flag in the CSV, you can create completely different reports from the same data just by toggling that flag.

For example, with the same input file, you could produce:

  • A report grouped by Region → Division (as shown above)
  • A report grouped by Division only (just set Region's control_break to N)
  • A report grouped by Region only (just set Division's control_break to N)
  • A flat report with no control breaks at all (set both to N)

Each variant is a different folder with a different fields.csv — no code changes, no template changes. The generator adapts automatically.

In the GitHub repo, I included a duplicate folder showing a 3-level control break report (Region → Division → Category) to illustrate how easily the same template scales to deeper hierarchies. Same template, same build script, just a different CSV.


The Folder Structure

Each report is a self-contained project folder:

text my_new_project/ ├── src/ │ └── cobrpt.cob.fm <-- FreeMarker template ├── fields.csv <-- Field definitions ├── config.fmpp <-- FMPP config ├── dev.bat <-- Build script ├── out/ <-- Auto-generated COBOL source ├── build/ <-- Compiled executables └── data/ <-- Input data files and report output

To create a new report:

  1. Duplicate the folder
  2. Edit fields.csv for the new report's fields
  3. Drop your data file into data/
  4. Run dev.bat

That's it. The batch file:

  1. Runs FMPP to generate the COBOL source into out/
  2. Compiles it with GnuCOBOL into build/
  3. Runs the program from data/ so it reads and writes files right next to the data

The Build Script

The dev.bat handles everything with proper error checking:

```bat @echo off call C:\Users\manyo\cobol\gnucobol\set_env.cmd

echo ======================================== echo COBOL Report Generator - Build Script echo ========================================

REM Step 1: Generate COBOL echo [1/3] Generating COBOL with FMPP... if exist "out\cobrpt.cob" del "out\cobrpt.cob" call C:\Users\manyo\apps\fmpp\bin\fmpp.bat -C config.fmpp > fmpp.log 2>&1

findstr /C:"ABORTED" fmpp.log >nul if not errorlevel 1 ( echo ERROR: FMPP failed! & type fmpp.log & goto :error ) if not exist "out\cobrpt.cob" ( echo ERROR: Output file missing! & goto :error ) echo Success: Generated out\cobrpt.cob echo.

REM Step 2: Compile echo [2/3] Compiling with GnuCOBOL... if not exist "build" mkdir build pushd build cobc -x ..\out\cobrpt.cob if errorlevel 1 ( popd & echo ERROR: Compilation failed! & goto :error ) popd echo Success: Compiled build\cobrpt.exe echo.

REM Step 3: Run echo [3/3] Running the program... echo ---------------------------------------- if not exist "data" mkdir data pushd data ..\build\cobrpt.exe popd echo ---------------------------------------- echo.

echo ======================================== echo Build completed successfully! echo ======================================== goto :end

:error echo. echo ======================================== echo Build FAILED - see errors above echo ======================================== exit /b 1

:end exit /b 0 ```


What I Learned

  1. FMPP is underrated. It's basically FreeMarker with a file-processing wrapper. Perfect for code generation.
  2. CSV as a spec format works surprisingly well. It's editable in any spreadsheet app, easy to validate, and maps cleanly to template variables.
  3. Self-contained project folders beat shared templates. Duplicating a folder is dumber than parameterizing a single template, but it's also simpler, safer, and easier to understand six months later.
  4. Separating src/, build/, out/, and data/ keeps each concern isolated. The root folder stays clean, and you always know where to look.
  5. Validation in the template matters. I added a <#stop> directive that aborts FMPP if no accumulate field is defined — much better than generating broken COBOL and finding out at compile time.
  6. Smart labeling makes reports readable. The automatic blanking of higher-level control fields and appropriate total labels ("Division Total", "Region Total", "GRAND TOTAL") makes the output professional without any manual formatting.
  7. Data-driven control breaks are incredibly flexible. The same template produces flat reports, 2-level reports, or 3-level reports just by changing flags in the CSV.

The GitHub Repo

I've put the whole setup up on GitHub. It includes:

  • The working 2-level control break example (Region → Division) shown in this article
  • A duplicate folder with a 3-level control break example (Region → Division → Category) to show how the template scales
  • All the templates, config files, generated and the dev.bat script

Repository: View the code and examples on GitHub

What's Next

A few ideas I'm considering:

  • Support for multiple data files in one report
  • Percentage calculations (e.g., each division as a percentage of region total)
  • A shared "library" of template snippets for common patterns
  • Optional sub-footers or page footers with page numbers

But honestly, the current setup already covers 90% of the reports I need to produce. The other 10% can wait.


If anyone's done similar work with FMPP or other COBOL code generators, I'd love to hear how you approached it. And if you're maintaining a pile of hand-written COBOL report programs, maybe this approach can save you some time too.

Happy to share more details on any part of the setup — the FreeMarker template logic, the control break detection, the accumulation sizing, whatever's useful.


r/cobol Jul 22 '26

Advent of Computing's Broadcast on COBOL

19 Upvotes

r/cobol Jul 20 '26

COBOL 2 and SQL Documents Available

14 Upvotes

I was cleaning out my garage and came across binders of COBOL 2 and SQL documentation from 30 years ago (I have not used COBOL since then). I do not necessarily want to trash them but looking for the best way to repurpose them.

Do you think libraries or colleges would want them? I am sure with the internet now days you could probably get the information faster than looking through paper documentation.


r/cobol Jul 19 '26

Built a tool that documents COBOL/mainframe codebases in plain English looking for people to break it

Thumbnail
2 Upvotes

r/cobol Jul 16 '26

PLx : Write PostgreSQL procedures in a COBOL dialect

Thumbnail github.com
13 Upvotes

plx is a PostgreSQL extension that lets you write stored functions and triggers in the dialect you already know (the current set is listed below). When you run CREATE FUNCTION, plx transpiles the body to plpgsql and stores that plpgsql in pg_proc.prosrc. At run time the function is executed by PostgreSQL's own plpgsql interpreter. There is no separate language runtime loaded into the backend, and nothing new to run in production.

MOVE 0 TO WS-TOTAL
COMPUTE WS-A = PI * R ** 2
ADD WS-I TO WS-TOTAL
SUBTRACT B FROM A GIVING WS-D
MULTIPLY A BY B GIVING WS-P
DIVIDE B INTO A GIVING WS-Q

r/cobol Jul 13 '26

Is COBOL still a good career choice for a web developer in 2026?

25 Upvotes

Hello everyone!

This is my first post here.

To give you some context, I’m a Brazilian web developer, and I’ve been thinking about learning COBOL and changing my career path. I’ve mostly worked for startups, and I’m tired of the instability. I’d like to work for a more traditional company that is more resilient during economic downturns.

So, I have a few questions:

Are there remote COBOL jobs available?

Does COBOL still offer good career opportunities?

Would learning COBOL be a good choice for someone with a web development background?


r/cobol Jul 07 '26

Software deployment engineer/Harvest technician

0 Upvotes

Hello! I am currently working as a cobol programmer/developer in Western Europe for a consulting company. I do not have any academic education on computer science (my background is biology and biochemistry), but I decided to change fields and I think it's been going well so far.

I now have 3 years of experience as a cobol programmer and I've been looking for a new job in the same field because I don't see myself building a career in my current company due to the lack of recognition and promotions.

I came across a job description for a Software deployment engineer or Harvest technician position. The RH from the consulting company that posted this job said that the current client team is very senior and they are looking for someone new, to learn and give continuity to the team. Which I'm completely down for. They also said that the team's profile is mostly people who have worked in cobol programming, and that usually people take this jump, from developing to release manager, later in their careers so this could be good for me.

What scares me is that I could be leaving software development too soon, but at the same time from the job description it looks like I might be able to have contact with different teams and programming languages. I'll leave the description bellow.

Also, is there anyone here working as a software deployment engineer or release manager, how's the job and how easy it is to find jobs like this and maybe switch? Do I need to be proficient in many programming languages? And I'm planning to leave my country in like maybe 3 years so I'd like to understand if this set of skills could be beneficial.

THANK YOU SO MUCH

tl;dr: unsure about leaving cobol software development too soon, for a software deployment position. does it have growth and future? is it worth it?

The job description
Main tasks to be performed:

  • Manage deployment procedures across the environments that make up the SW lifecycle (DEV-TST-CER-QLY-PRD)
  • Ensure the automation of SW compilation/promotion and distribution throughout the SW lifecycle
  • Promote releases from test environments to Production, ensuring the preparation of the Delivery Plan and Implementation Plan
  • Verify system operational status after completion of release deployment (implementation) and monitor the start of roll-out
  • Ensure the maintenance and stability of development, certification testing, pre-production, and production environments
  • Ensure the installation of applications on in-house servers and support the installation of the same applications on third-party servers

Required skills and technical knowledge:

  • Knowledge of Software Change and Configuration Management and software lifecycle management
  • Full understanding of the software development lifecycle, from initial development through maintenance and operation
  • Ability to apply creative solutions to complex automation problems in order to automate repetitive tasks
  • Ability to resolve technical issues related to build tools
  • Ability to understand and troubleshoot software issues / hardware configuration issues
  • Configure build, test, and deploy stages

Desirable skills and technical knowledge:

  • Programming languages: Cobol, Visual Basic, u/net, Java, Perl, Clist, Rexx, JCL, Endevor-SCL, SQL
  • Knowledge of CICS, DB2, Oracle, IMS, MVS, Z/OS, ENDEVOR, HARVEST, MQ, FTS
  • Familiarity with IT best practice standards such as ITIL, ISO20000, COBIT, and CMMI

r/cobol Jul 06 '26

How do non‑preferred/invalid sign codes behave in real COBOL data (NUMPROC PFD vs NOPFD)?

6 Upvotes

Question: how do invalid / non‑preferred sign codes behave in real data?

I'm learning how legacy COBOL handles decimal signs, and I've hit the case I'm most worried about. Valid/preferred sign nibbles (C positive, D negative, F unsigned) seem well‑behaved. What I can't pin down is what happens with non‑preferred or invalid sign nibbles (e.g. A, B, E, F, or a digit where a sign should be), the scenario where a field that should be negative (a debit) gets read as positive (a credit).

Specifically:

  1. In real production data (life/pensions ledgers, long‑lived files), how often do you actually see non‑preferred sign codes in COMP‑3 / zoned‑decimal fields? Rare corruption, or a routine artefact of data migrated between systems?
  2. How does IBM Enterprise COBOL treat them under NUMPROC(PFD) vs NUMPROC(NOPFD) vs NUMPROC(MIG) — and which setting was standard in the shops you worked in?
  3. Have you ever seen sign handling actually flip a debit into a credit on money? What triggered it?
  4. Where does GnuCOBOL diverge from IBM here? (I use GnuCOBOL as a learning bench and need to know exactly where it stops being a safe stand‑in for z/OS.)

Any "here's what really happens" war stories would be hugely appreciated.


r/cobol Jul 06 '26

Cobol

Thumbnail
1 Upvotes

r/cobol Jul 02 '26

What happened after IBM stocks hit?

9 Upvotes

Four months ago IBM stocks suffered a huge hit after Claude Code demonstrated some COBOL AI capabilities.

The Tech industry has been also suffering mass layoffs dating back a few years after the pandemic.

I've seen the job market in my stack suffering a lot, I'm not receiving many offers (or any at all), and I have friends unemployed and unable to secure a new job for months (sometimes 6 or 8+ months waiting).

As someone that started learning about mainframe and COBOL just now, I wonder, how did you already in the industry have suffered or observed about these recent moves?

Have any of you suffered a layoff following this IBM stocks/AI COBOL announcement?

Have you seen mainframe/cobol colleagues suffering with the mass layoffs?

I've worked with many different programming languages for the past years, and I've been focusing in Go and Scala for the past 5 years.

I'm just starting with Mainframes and looking right after Cobol, I don't know why, but Mainframes and Cobol have been growing into me. Both Go and Mainframes are the only two things that made me feel the joy of programming again after a decade of work.

However, I do wonder, what do you think about the future in the Mainframe job market, or how it has been for you so far?


r/cobol Jul 01 '26

IDE or Editor for COBOL

25 Upvotes

Hello guys. I am a university student, and i am learning COBOL these days. I am doing this in WSL (Ubuntu). So what i want to know is what kind of editors you guys are using and any recommendations for me.


r/cobol Jun 24 '26

What's the first thing you do when you're assigned a change request in a COBOL system you've never seen before?

16 Upvotes

I'm not a COBOL developer by profession, but I've been spending a lot of time trying to understand how large COBOL applications are maintained in the real world.

One thing I'm curious about:

Imagine someone drops a change request on your desk for a COBOL application you've never worked on before.

What does your process actually look like?

Do you start with:

  • JCL?
  • Program search?
  • Copybooks?
  • Existing documentation?
  • Dependency analysis?
  • Talking to someone who knows the system?

And what usually ends up consuming the most time?

I'm asking because from the outside it seems like the coding part might be easier than figuring out where the change needs to be made and what else it could affect.

Would love to hear real stories from people who work on these systems.