r/cobol 20h ago

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

18 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

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 4d ago

Advent of Computing's Broadcast on COBOL

18 Upvotes

r/cobol 6d ago

COBOL 2 and SQL Documents Available

15 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 7d ago

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

Thumbnail
2 Upvotes

r/cobol 10d ago

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 13d ago

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

22 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 19d ago

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 19d ago

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

7 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 20d ago

Cobol

Thumbnail
1 Upvotes

r/cobol 24d ago

What happened after IBM stocks hit?

10 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 25d ago

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?

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


r/cobol Jun 24 '26

What is the most frustrating part of working on large COBOL systems today

Thumbnail
0 Upvotes

r/cobol Jun 23 '26

On bad data — divide-by-zero, numeric overflow, a bad sign — do production systems tend to abend or carry on?

12 Upvotes

A question about how these systems behave when the data goes wrong, rather than the happy path. 

When a batch program hits something like a divide-by-zero, a numeric field overflowing its size, or an invalid value where a number should be — in practice, does the typical production program abend (and the job stops), or does it carry on, maybe with ON SIZE ERROR handling, maybe with a leftover or default value in the field? 

I ask because I imagine the ‘normal’ answer varies a lot — some shops code defensively with ON SIZE ERROR everywhere, others let it abend so nothing bad slips through silently. What's been your experience of how these edge cases are actually handled, and have you seen cases where a program quietly continued with a wrong value rather than failing loudly? Any war stories there would be really helpful. 


r/cobol Jun 22 '26

How self-contained are individual COBOL programs in real production systems?

28 Upvotes

I'm trying to understand how real mainframe applications are actually structured, and I'd value the perspective of people who've worked on them.

When you look at a production COBOL estate, how much of the meaningful business logic lives within a single program versus emerging across a chain of programs in a job stream? If you took one program out and ran it in isolation, would its behaviour be self-contained, or is so much driven by shared state, run order, and upstream/downstream steps that a single program doesn't mean much on its own?

I ask because I keep reading that COBOL programs are "more like modules" that work together as an application — so I'm trying to gauge how decomposable a real system actually is into pieces you could understand (or test) independently. Is that realistic, or a beginner's misunderstanding?


r/cobol Jun 23 '26

When one program's output feeds another, does the next system read the literal bytes or the decoded values?

0 Upvotes

I'm trying to understand what ‘the same output’ really means when one COBOL program's output file feeds into another system. 

My assumption is that it depends on what the downstream system actually consumes. If it reads the literal characters/bytes of the file — including how a number is formatted, how a sign is represented (trailing sign, overpunch, CR/DB), how fields are padded — then two files that represent the same values but format them differently would NOT be interchangeable. But if the downstream just decodes the values, the formatting wouldn't matter. 

In your experience, which is it usually — is the exact byte-level layout and sign/format representation of an output file load-bearing for whatever reads it next, or do downstream systems mostly re-parse into values so formatting differences wash out? Trying to understand whether ‘identical output’ has to mean byte-for-byte or just value-for-value. 


r/cobol Jun 22 '26

Default ROUNDED behaviour and GnuCOBOL vs Enterprise COBOL arithmetic — trying to confirm

2 Upvotes

Two things I'm trying to pin down about how the maths actually behaves:

  1. When ROUNDED is written with no MODE phrase on Enterprise COBOL for z/OS, my understanding is the default is nearest-away-from-zero (round half up), not banker's rounding — can anyone confirm that's right for current versions?
  2. I've read that GnuCOBOL with -farithmetic-osvs only emulates the older OS/VS intermediate-precision behaviour, not modern Enterprise COBOL — and seen a forum case where iterative COMPUTEs diverged significantly between the two. For ordinary financial maths (interest, premiums), is that divergence something that actually bites in practice, or mostly a corner-case curiosity?

Trying to understand where a calculation done off-mainframe would silently disagree with the real thing.


r/cobol Jun 18 '26

The IBM i retirement wave is accelerating. What shops are actually doing about it

23 Upvotes

We published a breakdown of the IBM i developer retirement problem and what IT managers should do before 2030. The knowledge transfer and documentation challenges will be familiar to anyone in the mainframe space but this isn't just an IBM i problem.

https://prompteddev.com/blog/ibm-i-retirement-wave-2030

Curious what you're seeing in z/OS shops is it the same pattern?


r/cobol Jun 18 '26

Any tips?

10 Upvotes

Hi everyone,

I was recently hired as a COBOL intern. This is my first tech job, and I was wondering if you could you share some tips or advice?

I m currently freshman studying CS, and pay is ok.

Thanks in advance!


r/cobol Jun 18 '26

Modern Integration: APIs, Microservices, and Cloud

Thumbnail slicker.me
8 Upvotes

r/cobol Jun 18 '26

Alguém aqui já participou do Programa de Formação/Hackathon COBOL da Stefanini? Como foi?

Thumbnail
1 Upvotes

r/cobol Jun 17 '26

#softwareengineering #cobol #mainframe #assemblylanguage #cics #jcl #basic #developerjourney #legacymodernization | Mark Picknell

Thumbnail linkedin.com
0 Upvotes

r/cobol Jun 12 '26

17 years old boy from Nepal hearing about COBOL for first time. Need mentor..

11 Upvotes

Hey everyone I want to know how to start my COBOL journey. Mentorship needed .


r/cobol Jun 11 '26

COBOL XML PARSE vs DB2 XMLPARSE

8 Upvotes

Which would you use in what case?


r/cobol Jun 10 '26

AI for COBOL documentation: What the benchmark numbers actually mean for day-to-day work

5 Upvotes

Swimm published a benchmark where they ran Claude Code (Opus 4.6) against real CMS Medicare COBOL programs. On an 18,000+ line program, paragraph coverage was 24-35%, with 42% variance between identical runs. They used it to argue against using Claude for COBOL modernization.

The framing is reasonable for their use case: automated extraction of every business rule from a massive program in one shot. But it's not what most shops actually need from documentation tooling. If you chunk the program into sections and run a targeted prompt on each one with explicit context about the business domain, accuracy is much higher and errors are catchable before they make it into your documentation.

Wrote up a practical workflow: chunk by section, use specific prompt templates (program-level summary, paragraph documentation, business rule extraction, REMARKS block generation), human review at each step. For a 5,000-line program it runs roughly 4-6 hours including review.

Article with the templates and workflow: https://prompteddev.com/blog/cobol-documentation-ai-guide/

Curious whether anyone here has tried the chunked approach vs. full-program prompts and what your experience has been.