Naming and Coding Standards
Naming and Coding Standard — COBOL[edit]
| Field | Value |
|---|---|
| Document ID | PGCBL-NCS-001 |
| Document Type | Naming and Coding Standard |
| System | pgcobol — Prime Numbers Application v1.0 |
| Applies to | All GnuCOBOL source files (.cbl) and copybooks (.cpy)
|
| Version | 1.0 |
| Status | Approved |
| Owner | Lead Developer |
| Author | Derived from: IBM Enterprise COBOL Coding Guidelines, GnuCOBOL Best Practices, Micro Focus COBOL Standards, and observation of existing pgcobol source |
| Created | 2026-03-17 |
| Last modified | 2026-03-17 |
| Classification | Internal |
Version History[edit]
| Version | Date | Author | Status | Change Summary |
|---|---|---|---|---|
| 0.1 | 2026-03-17 | — | Draft | Initial standard from source analysis |
| 1.0 | 2026-03-17 | — | Approved | Baselined |
Table of Contents[edit]
- Standards Basis
- Source File Conventions
- Division and Section Structure
- Data Naming Conventions
- Paragraph Naming Conventions
- Procedure Division Coding Rules
- SQL Embedding Conventions
- Commentary Standards
- Copybook Standards
- Method-Dispatch Pattern Standard
- Error Handling Standard
- Compliance Checklist
- Open Issues
1. Standards Basis[edit]
This standard synthesises rules from the following well-known and published sources:
| Source | What it contributes |
|---|---|
| ISO/IEC 1989:2014 (COBOL 2014 standard) | Syntax compliance baseline |
| IBM Enterprise COBOL Programming Guide (SC27-1460) | Naming conventions, data division layout, structured programming |
| Micro Focus COBOL Coding Standards | Paragraph prefixing, copybook discipline, comment headers |
| GnuCOBOL Programmer’s Guide | GnuCOBOL-specific extensions and limitations |
| NIST COBOL Test Suite conventions | Identifier uniqueness and column discipline |
| Yourdon / Constantine structured design | Module cohesion, coupling reduction — applied to COBOL tiers |
| pgcobol source | Existing conventions extracted and formalised |
2. Source File Conventions[edit]
2.1 File names[edit]
<program-id>.cbl Main program source <copybook-name>.cpy Copybook source <program-id>.cbsql GixSQL pre-processor input (if SQL present) <program-id>_cbsql.out GixSQL pre-processor listing (generated; do not edit)
- All lowercase.
- Hyphens as word separators (not underscores) for new files. Underscores are a legacy convention in this codebase (
primes_table.cpy); new files use hyphens. - The
PROGRAM-IDin the source must match the filename exactly (case-insensitive).
2.2 Column discipline[edit]
GnuCOBOL supports both fixed-format (traditional) and free-format source. This codebase uses fixed format:
Columns 1–6 Sequence number area (blank in new code; used by legacy tools) Column 7 Indicator area: space = code, * = comment, / = page eject, - = continuation Columns 8–11 Area A: DIVISION, SECTION, paragraph names, 01/77-level data Columns 12–72 Area B: all other code Columns 73–80 Identification area (optional; ignored by compiler)
Rule: All paragraph names and top-level items begin in column 8 (Area A). All subordinate code begins at column 12 or beyond (Area B).
3. Division and Section Structure[edit]
3.1 Mandatory division order[edit]
Every program must contain these divisions in this order:
IDENTIFICATION DIVISION.
PROGRAM-ID.
(AUTHOR. — optional)
(DATE-WRITTEN. — optional)
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER.
OBJECT-COMPUTER.
SPECIAL-NAMES.
INPUT-OUTPUT SECTION. (only if files are used)
FILE-CONTROL.
DATA DIVISION.
FILE SECTION. (only if files are used)
WORKING-STORAGE SECTION.
LINKAGE SECTION. (only for called programs)
PROCEDURE DIVISION [USING ...].
3.2 Working-Storage section order[edit]
Items in WORKING-STORAGE must appear in this order:
- Debug marker filler (01 FILLER PIC X(32) VALUE “Start WS <program>”) — for memory-dump readability.
- File status fields (if any files).
- Constants (01 level, VALUE clause, no modification at runtime).
- Work fields grouped by function.
- COPY statements for local copybooks (primes-ui, primes-dal, etc.).
3.3 Linkage section[edit]
The linkage section must contain only COPY statements referencing the published inter-tier copybooks. No fields should be defined directly in the LINKAGE SECTION of a standard program.
4. Data Naming Conventions[edit]
4.1 General rules[edit]
| Rule | Rationale |
|---|---|
Use hyphens as word separators: test-number, not testNumber or test_number
|
COBOL convention; underscores are non-standard in some compilers |
| Maximum name length: 30 characters (COBOL 85 limit) | Portability |
| Names must be meaningful: no single-letter names except loop indexes | Readability |
Avoid COBOL reserved words and common abbreviations that conflict (e.g. LENGTH, SPACE)
|
Prevents ambiguity |
| Prefix 88-level condition names with the purpose they test, not the field name | dal-method-ok not dal-result-zero
|
4.2 Level number conventions[edit]
| Level | Use |
|---|---|
| 01 | Group items, independent items, copybook roots |
| 03, 05, 07 | Subordinate group and elementary items (use odd numbers: 01, 03, 05, 07 …) |
| 66 | RENAMES clause (use sparingly) |
| 77 | Independent elementary items (prefer 01 unless 77 is clearly appropriate) |
| 88 | Condition names; always immediately under the field they qualify |
Rule: Use odd-numbered levels (01, 03, 05, 07, 09) to allow insertion of intermediate levels without renumbering. Never use even levels in new code.
4.3 Naming prefixes for scope[edit]
| Prefix | Meaning | Example |
|---|---|---|
r-
|
Record / row field (fetched from DB) | r-ident, r-prime
|
u-
|
UI-layer field (in primes-ui block) | u-sequence, u-number
|
t-
|
Table cell / temporary print field | t-ident, t-prime
|
f-
|
Formatted / print-ready field | f-page-number
|
w-
|
Work field (local computation) | w-remainder
|
4.4 Picture clause conventions[edit]
| Type | Preferred PICTURE | Notes |
|---|---|---|
| Positive integer, display | 9(n)
|
n ≤ 9 for standard arithmetic |
| Signed integer, display | S9(n)
|
Use S prefix for fields that can go negative or are SQL host variables |
| Packed decimal | S9(n) COMP-3
|
For high-volume arithmetic and SQL host variables |
| Binary integer | S9(n) COMP-5
|
For SQLCA fields and counters needing maximum performance |
| Fixed decimal | 9(n)V9(m)
|
V = implied decimal point; no actual decimal character stored |
| Alphanumeric | X(n)
|
For text, method verbs, messages |
| Edited numeric (print) | Z(n)9 or Z(n)
|
For zero-suppressed print output only; never used in arithmetic |
| Boolean flag | 9(1) with 88-levels
|
e.g. PIC 9 VALUE 1. 88 new-page VALUE 1.
|
4.5 88-level condition names[edit]
- Must be named for what is true when the condition fires, not for the value:
session-method-oknotresult-is-zero. - Result-code 88-levels must cover all meaningful values; add a
88 invalid-method VALUE "bad"sentinel. - Multiple conditions for the same field must have non-overlapping VALUES.
4.6 Copybook field naming[edit]
- Fields in a copybook must be globally unique across all copybooks in the project (COBOL does not namespace copybooks).
- Prefix copybook fields with the copybook’s logical name:
dal-methods,ui-method-result,session-result.
5. Paragraph Naming Conventions[edit]
This project uses a prefix-number naming scheme derived from IBM COBOL shop practice:
5.1 Prefix codes[edit]
| Prefix | Meaning | Example |
|---|---|---|
r
|
Regular processing paragraph (business logic, I/O) | r80-test-number
|
s
|
System / infrastructure paragraph (DB connect, file open) | s00-connect
|
e
|
Error-handling paragraph | e10-handle-db-error
|
x
|
Exit / cleanup paragraph (always PERFORM last) | x99-shutdown
|
Observation from existing source: The project uses
randsprefixes already. Theeandxprefixes are introduced here as an extension. Ther99convention for shutdown paragraphs is retained.
5.2 Numbering[edit]
- Two-digit sequence:
00,10,20…90,99. - Low numbers (00–29): initialisation / setup.
- Mid numbers (30–79): main processing.
- High numbers (80–89): sub-processing / helpers.
- 90–98: cleanup and close.
- 99: final exit / stop.
- Leave gaps of 10 between paragraphs to allow insertion.
5.3 Name format[edit]
<prefix><NN>-<short-hyphenated-description> Examples: r80-test-number r82-next-test-number r85-write-prime r89-get-next-divider r90-start-primes-report r99-close-primes s00-connect s01-cursor s02-fetch s99-disconnect
5.4 Rules[edit]
- Paragraph names must be unique within the program.
- A paragraph must do one thing. If it needs a comment explaining “also does X”, split it.
- Paragraphs called only from one place may be inlined (PERFORM vs inline code) — choose consistency over micro-optimisation.
- Never use
GO TOexcept for the structuredGO TO <paragraph>used as a skip (an accepted COBOL idiom). Do not useALTER.
6. Procedure Division Coding Rules[edit]
6.1 Structured programming[edit]
All control flow must use structured constructs:
| Construct | Use for |
|---|---|
PERFORM <paragraph>
|
Single call to a named paragraph |
PERFORM <paragraph> UNTIL <condition>
|
Loops with pre-test condition |
EVALUATE TRUE … WHEN … END-EVALUATE
|
Multi-way branch (preferred over nested IF) |
IF … ELSE … END-IF
|
Two-way branch |
NEXT SENTENCE
|
Skip remainder of sentence (used sparingly; prefer END-IF) |
Never use: - GO TO (except structured skip idiom in legacy contexts) - ALTER - PERFORM … THRU (couples paragraphs; prefer explicit PERFORM chains)
6.2 EVALUATE TRUE convention[edit]
The method-dispatch EVALUATE always takes this form:
<syntaxhighlight lang="cobol">EVALUATE TRUE
WHEN <condition-name-1> PERFORM <paragraph> WHEN <condition-name-2> PERFORM <paragraph> WHEN OTHER MOVE 1 TO <result-field>
END-EVALUATE.</syntaxhighlight>
- Every EVALUATE must have a
WHEN OTHERclause. - The
WHEN OTHERmust set a meaningful error indicator; it must never be a no-op.
6.3 PERFORM … UNTIL[edit]
- The loop condition is checked before the first iteration (test-before / DO-WHILE reversed).
- Infinite loops are not permitted. Every PERFORM UNTIL must have a reachable exit condition.
- Loop termination must be tested and documented in the program logic guide.
6.4 CALL conventions[edit]
- All inter-program calls use
CALL "literal" USING <data-block>. - The called program name must be a string literal, not a data name (for static linkage and security).
- Always check the result field of the called program’s control block immediately after the CALL.
6.5 Arithmetic[edit]
- Use
COMPUTEfor complex expressions:COMPUTE x = a ** 0.5. - Use
ADD … TO,SUBTRACT … FROM,MULTIPLY … BY,DIVIDE … BY … GIVING … REMAINDERfor simple operations. - Always use
GIVINGandREMAINDERclauses to avoid in-place modification of source operands. - Always check for zero divisor before DIVIDE.
- Declare intermediate results with sufficient precision to avoid truncation:
PIC 9(9)V9(9)for square-root results.
7. SQL Embedding Conventions[edit]
7.1 EXEC SQL block layout[edit]
<syntaxhighlight lang="cobol"> EXEC SQL [AT <connection-alias>]
<sql statement>
END-EXEC.</syntaxhighlight>
EXEC SQLon its own line, indented to Area B.- SQL keywords in uppercase.
- Host variable prefix
:immediately before the variable name, no space. END-EXEC.on its own line, followed by a period.
7.2 Host variable declaration[edit]
- All SQL host variables must be declared via
EXEC SQL INCLUDE <copybook> END-EXECor directly in WORKING-STORAGE. - Host variables for row-level data must be grouped under a 01-level record that mirrors the table structure.
- Use
COMP-3for numeric host variables for performance.
7.3 SQLCODE checking[edit]
Every EXEC SQL block must be followed immediately by a SQLCODE check:
<syntaxhighlight lang="cobol"> EXEC SQL ... END-EXEC.
IF SQLCODE = 0 THEN
<success path>
ELSE
MOVE SQLERRMC TO program-message
PERFORM e10-handle-sql-error
END-IF.</syntaxhighlight>
- Never fall through after an unchecked SQL statement.
- Log
SQLCODEandSQLERRMCon every error path.
7.4 Cursor naming[edit]
<table-name>cursor Example: primescursor (cursor on the primes table)
7.5 Connection alias naming[edit]
<database-name> Example: primes (alias for the primes database connection)
The alias must be consistent across all AT <alias> clauses and the CONNECT/RESET statements.
8. Commentary Standards[edit]
8.1 Program header block[edit]
Every .cbl file must open with a standardised comment block in columns 7–72:
<syntaxhighlight lang="cobol"> *=================================================================
* Program: <PROGRAM-ID>
* Document: <PGCBL-PLG-NNN>
* Purpose: <one sentence>
* Tier: Orchestrator | Business Logic | Data Access | UI
* Calls: <list of programs this program calls>
* Called by: <list of programs that call this program>
* Copybooks: <list of copybooks copied>
* Author: <name>
* Created: YYYY-MM-DD
* Modified: YYYY-MM-DD <name> <change summary>
*=================================================================</syntaxhighlight>
8.2 Paragraph headers[edit]
Every paragraph must have a comment immediately before it:
<syntaxhighlight lang="cobol"> *-----------------------------------------------------------------
* r80-test-number
* Tests whether test-number is prime by trial division.
* Called by: PERFORM UNTIL test-number = 999999999
* Uses: test-number, test-divider, test-number-sqr, test-rest
*-----------------------------------------------------------------
r80-test-number.</syntaxhighlight>
8.3 Inline comments[edit]
- Use
*>(GnuCOBOL free-format inline comment) or a*in column 7 for a full-line comment. - Comment the why, not the what: the code shows what; the comment explains why.
- Every EXEC SQL block must have a comment above it stating what it does and under what conditions it is called.
<syntaxhighlight lang="cobol"> * Fetch the next prime from the cursor.
* Called after every successful report loop iteration.
EXEC SQL FETCH primescursor INTO :primes-row END-EXEC.</syntaxhighlight>
8.4 Prohibited comment patterns[edit]
- Do not comment out code and leave it in the source permanently. Use version control instead.
- Do not write comments that merely restate the code:
* MOVE 1 TO X (moves 1 to X).
9. Copybook Standards[edit]
9.1 File name and content rules[edit]
- Each copybook defines exactly one logical structure (one 01-level group).
- The copybook file name matches the 01-level name:
primes-dal.cpydefines01 primes-dal. - Copybooks must not contain PROCEDURE DIVISION code.
- Copybooks must not contain COPY statements (no nested copies).
9.2 Copybook header[edit]
Every copybook must open with:
<syntaxhighlight lang="cobol"> *=================================================================
* Copybook: <name>.cpy
* Purpose: <one sentence>
* Used by: <list of programs>
* Document: <PGCBL-DDD-001> §<section>
*=================================================================</syntaxhighlight>
9.3 Change control[edit]
- Any change to a copybook is a breaking change for all programs that include it.
- Changes must be accompanied by a recompilation of all affected programs.
- The copybook version history must be updated in the header comment.
9.4 Canonical copybook rule[edit]
Where two copybooks define the same structure (e.g. primes-table.cpy and primes_table.cpy), one must be designated canonical and the other deprecated and removed. The canonical version is documented in the Data Dictionary.
10. Method-Dispatch Pattern Standard[edit]
This pattern is the core inter-tier communication mechanism. These rules ensure it is applied consistently.
10.1 Control block layout[edit]
<syntaxhighlight lang="cobol"> 01 <tier>-<control-block>.
03 <tier>-methods PIC X(32).
88 <verb-1> VALUE "<verb-1-string>".
88 <verb-2> VALUE "<verb-2-string>".
88 invalid-method VALUE "bad".
03 <data-payload-group>.
05 <field-1> PIC ...
03 <tier>-result PIC 9(2) VALUE ZERO.
88 <tier>-method-ok VALUE 0.
88 <tier>-method-nok VALUE 1.
88 <tier>-method-eof VALUE 9.</syntaxhighlight>
10.2 Result code convention[edit]
| Value | 88-level name | Meaning |
|---|---|---|
| 0 | <tier>-method-ok
|
Operation succeeded |
| 1 | <tier>-method-nok
|
Operation failed (error) |
| 9 or 99 | <tier>-method-eof
|
End of data (cursor exhausted, no more rows) |
- All tiers must use these values consistently.
- No other result codes may be introduced without updating this standard and the Data Dictionary.
10.3 Caller obligations[edit]
<syntaxhighlight lang="cobol"> MOVE "<verb>" TO <tier>-methods.
CALL "<program>" USING <control-block>.
IF <tier>-method-ok THEN
<success path>
ELSE
<error path — must not be empty>
END-IF.</syntaxhighlight>
- The caller must always check the result immediately after the CALL.
- An unchecked result is a coding error.
10.4 Callee obligations[edit]
- The callee must set the result field before EXIT PROGRAM on every code path.
- The callee must handle
WHEN OTHERin the EVALUATE and set result to 1 (nok). - The callee must not STOP RUN (only EXIT PROGRAM); the caller decides whether to stop.
11. Error Handling Standard[edit]
11.1 SQL errors[edit]
Every EXEC SQL block must check SQLCODE as specified in §7.3. On error:
- Move
SQLERRMCtoprogram-message. - Set the tier’s result field to 1 (nok).
- Call primesui with
ui-methods = "log-message"to log the error. - EXIT PROGRAM — do not STOP RUN from within a subprogram.
11.2 File I/O errors[edit]
Every file OPEN, READ, WRITE, CLOSE must check the file-status field:
<syntaxhighlight lang="cobol"> IF <file>-status = "00" THEN
<success>
ELSE
MOVE <file>-status TO program-message
PERFORM r98-message-ui
MOVE 1 TO ui-method-result
END-IF.</syntaxhighlight>
11.3 Return code[edit]
At the end of primesmain (the only STOP RUN in the system), set the process return code:
<syntaxhighlight lang="cobol"> IF <any-error-indicator> THEN
MOVE 1 TO RETURN-CODE
ELSE
MOVE 0 TO RETURN-CODE
END-IF.
STOP RUN.</syntaxhighlight>
12. Compliance Checklist[edit]
Use this checklist during code review:
Structure[edit]
- ☐ Program header block present and complete.
- ☐ All divisions in correct order.
- ☐ WORKING-STORAGE follows the prescribed section order.
- ☐ LINKAGE SECTION contains only COPY statements.
Naming[edit]
- ☐ All paragraph names follow
<prefix><NN>-<description>scheme. - ☐ All data names use hyphens, not underscores (except legacy names).
- ☐ 88-level names describe the true condition, not the value.
- ☐ Copybook fields are globally unique and prefixed with the copybook’s logical name.
Procedure Division[edit]
- ☐ No GO TO (except structured skip).
- ☐ No PERFORM … THRU.
- ☐ Every EVALUATE has WHEN OTHER.
- ☐ Every CALL is followed by a result check.
- ☐ Every EXEC SQL is followed by a SQLCODE check.
- ☐ Every file operation is followed by a file-status check.
- ☐ RETURN-CODE is set before STOP RUN in primesmain.
Comments[edit]
- ☐ Every paragraph has a comment header.
- ☐ Every EXEC SQL block has a purpose comment.
- ☐ No commented-out code left in permanent source.
Copybooks[edit]
- ☐ Each copybook defines exactly one 01-level structure.
- ☐ Copybook file name matches the 01-level name.
- ☐ No nested COPY statements.
- ☐ Copybook header present.
13. Open Issues[edit]
| ID | Issue | Owner | Target | Status |
|---|---|---|---|---|
| OI-01 | primes_table.cpy (underscore) needs to be designated as deprecated in favour of primes-table.cpy (hyphen)
|
Developer | — | Open |
| OI-02 | No program header blocks present in current source — all four programs need retrofitting | Developer | — | Open |
| OI-03 | No paragraph comment headers present in current source — all paragraphs need retrofitting | Developer | — | Open |
| OI-04 | Direct DISPLAY statements in primes.cbl bypass the structured log format; should be replaced with calls to primesui
|
Developer | — | Open |
| OI-05 | RETURN-CODE not set in primesmain; needs adding before STOP RUN
|
Developer | — | Open |
Terug naar: Design standards | Cobol and PostgreSQL