Repository navigation
Program Described Files I Specs and O Specs
Everything in the Record-Level Access chapter runs against a database table over ODBC. Program-described files are the other kind: flat files with a byte-position field layout, described by I-specs and O-specs rather than by an external descriptor. They are available from fixed-format source only.
Real IBM i program-described files are pure fixed-width bytes on a
record-oriented file system, which has no equivalent on macOS, Linux or
Windows. OpenRPG uses a portable convention instead: one record per line —
exactly the declared record length in bytes, right-padded with spaces or
truncated to fit, followed by a newline. Fixed width makes byte-offset seeking
for UPDATE trivial.
Numeric fields are stored as plain ASCII digits, right-justified and
zero-padded, with an implied decimal point and an optional leading -. This is
an OpenRPG interchange format, not literal IBM i on-disk semantics.
HDFTACTGRP(*NO)
FTESTFL154 UF A F 25 DISK
DTMPDSP S 52A
ITESTFL154 AA
I A 1 20 NAME
I S 21 25 0AGE
/free
NAME = 'Alice';
AGE = 30;
EXCEPT;
NAME = 'Bob';
AGE = 25;
EXCEPT;
NAME = 'Carol';
AGE = 40;
EXCEPT;
/end-free
C READ TESTFL154
C DOW NOT %EOF(TESTFL154)
C EVAL TMPDSP = %TRIM(NAME)
C TMPDSP DSPLY
C EVAL TMPDSP = %CHAR(AGE)
C TMPDSP DSPLY
C READ TESTFL154
C ENDDO
C RETURN
OTESTFL154 EADD
O NAME 20
O AGE 25The F-spec says UF A F: an update file (position 17), full procedural,
read with operation codes (18, required for input and update files, IBM:
RNF2093), records may be added (20), and F in position 22 for
program-described. The record length is in positions 23-27. Field names from
the I-spec become ordinary program variables. Specifications come in the order
H, F, D, I, C, O (IBM: RNF0257).
An I-spec file has one record identification line per record type, optionally followed by field description lines.
Record identification:
| Positions | Field |
|---|---|
| 7-16 | File name |
| 21-22 | Record identifying indicator |
| 23-30, 31-38, 39-46 | Up to three identification code sets |
Each code set is a position, an optional N, a code part and a character —
which together say "the byte at this position is (or is not) this character".
Only code part C (character) is supported; the EBCDIC-era zone (Z) and digit
(D) tests are rejected.
Field description:
| Positions | Field |
|---|---|
| 36 | Data format |
| 37-41 | From byte position |
| 42-46 | To byte position |
| 47-48 | Decimal positions |
| 49-62 | Field name |
| 63-64 | Control level (L1-L9) |
| 69-70 | Plus indicator |
| 71-72 | Minus indicator |
| 73-74 | Zero-or-blank indicator |
Date, time, timestamp, graphic and indicator formats (D/T/Z/G/N) are
rejected at parse time — a CHAR field still works fine for date text if you
do not need real date parsing.
Control levels in positions 63-64 parse and are accepted, but do not yet set anything at run time.
Output records are exception records: E in position 17 of the record line
(IBM requires a type there, RNF6005), written by the EXCEPT operation. ADD
in positions 18-20 adds a new record; without it, a record for an update file
rewrites the one last read. An EXCEPT name in positions 30-39 lets a program
write one record and not another. The heading, detail and total types (H,
D, T) are written by the RPG cycle, which OpenRPG does not implement.
Each record line is followed by one field or constant line each:
| Positions | Field |
|---|---|
| 30-43 | Field name — blank if a constant is given instead |
| 44 | Edit code |
| 45 | Blank-after (B) |
| 47-51 | End position |
| 53-80 | Constant or edit word |
Field width is inferred from the gap to the previous field's end position, not
from the field's own declared length. End positions must be absolute — the
relative +n/-n forms are not supported. Edit codes use the same engine as
%EDITC, and the end position must leave room for what the edit code adds
(IBM: RNF8003).
OTESTFL157 EADD NEWNOTE
O NOTE 20
OTESTFL157 E CHGNOTE
O NOTE 20EXCEPT NEWNOTE adds a record; EXCEPT CHGNOTE rewrites the one just read.
EXCEPT with no name writes the records that have none.
| Opcode | Behavior |
|---|---|
READ |
Sequential read, dispatching on record type |
EXCEPT |
Write the E output records: add, or rewrite the record just read |
WRITE and UPDATE on a program-described file take a data structure holding
the record on IBM i (RNF5191 without one), which OpenRPG does not support; use
EXCEPT. CHAIN, SETLL, SETGT and DELETE are not supported on
program-described files — keyed access needs F-spec key-field columns that are
not modeled for them. O-spec spacing and skipping, and printer paging, are also
unavailable; there is no PRINTER runtime in this compiler for any file type.
A program writes READ MYFILE; regardless of which kind of file MYFILE is —
the compiler picks the flat-file or the RLA path from the declaration.
- Installation
- Quick Start
- CLI Reference
- Language Basics
- Data Types
- Variables and Constants
- Data Structures
- Arrays
- Varying-Dimension Arrays
- Control Flow
- Procedures
- Procedure Overloading
- Built-In Functions
- Error Handling
- Operation Extenders
- Enumerations
- Program Status Data Structure
- Data Areas
- SND-MSG
- Embedded SQL
- Record-Level Access
- Display Files (WORKSTN)
- Program-Described Files (I-Specs and O-Specs)
- DATA-INTO and DATA-GEN
- XML-INTO
- Fixed-Format Source
- Database Connections
- Multi-Module Programs
- Environment Variables
- Testing
- Complete Example: Employee Report
- IBM i Conformance Results
- IBM i Execution Results