Supported RPG Features

A free-format DCL-F PRINTER file writes report lines with an explicit two-operand WRITE, where the second operand is the source record - a data structure (or character field) whose storage supplies the printed line image:

**FREE
dcl-f QSYSPRT printer(132) oflind(*in99);
dcl-ds outRec;
  text char(132);
end-ds;
dcl-s i int(5);

for i = 1 to 130;
  if *in99;                       // overflow reached - reprint the heading
    text = 'ACME REPORT';
    write QSYSPRT outRec;
    *in99 = *off;                 // clear it; it re-arms on the next page
  endif;
  text = 'Detail line ' + %char(i);
  write QSYSPRT outRec;
endfor;
*inlr = *on;

The record image is the source data structure's storage laid out subfield by subfield in declaration order: a character subfield contributes its characters; a zoned subfield its zoned digit image (a negative value carries the sign as the EBCDIC overpunch on the units digit); a date, time, or timestamp subfield its character storage image (the field's DATFMT/TIMFMT text - e.g. *ISO yyyy-mm-dd, hh.mm.ss, yyyy-mm-dd-hh.mm.ss.ffffff). A packed, integer, unsigned, float, or binary subfield occupies its byte width as blanks, since its BCD/binary storage is not a printable character image - pre-edit such values into a character subfield if they must appear on the report. A single character field may be written directly. A program whose only file is a PRINTER needs no database connection.

A VARYING subfield occupies 2 + maxLen columns: its storage is a 2-byte binary length prefix followed by the value left-justified in the declared maximum data area. The prefix is not printable, so it prints as two blanks and the value starts at the subfield's third byte. For example a data structure of a char(3) inz('ABC'), v varchar(5) inz('XY'), b char(3) inz('END') prints:

ABC  XY   END
``` - `ABC`, two blanks for the length prefix, `XY`, three blanks for the unused
remainder of the 5-byte data area, then `END`. Declare the subfield as fixed
`char` instead if you want the value flush against the preceding one.

**Page overflow (`OFLIND`).** `OFLIND(*INxx)` names an overflow indicator that
turns on when a `WRITE` reaches the page overflow line. The indicator is
**edge-triggered**: it is set on once when the overflow line is reached, and it
is the program's responsibility to test it, print headings, and clear it - it
is not re-asserted on every subsequent write. On the next page it re-arms and
fires again when the overflow line is crossed, so an overflow-conditioned
heading prints once per page.

**Form geometry (`FORMLEN` / `FORMOFL`).** `FORMLEN(n)` sets the form length
(total lines per page) and `FORMOFL(n)` sets the overflow line. The defaults
are a 66-line form with overflow at line 60 - so with default geometry the
first `WRITE` prints on line 1 and `*INxx` first turns on after the line that
advances the paper to line 60. When the form length is passed, the page wraps
to line 1 and the overflow indicator re-arms.

**In fixed format**, the same `WRITE` is written as a C-spec naming the file in
factor 2 and the source data structure in the **result** field - the operand
positions used for a program-described `WRITE`:

FQSYSPRT O F 132 PRINTER DREC DS D A 3A INZ('ABC') D C 5A INZ('XY') D B 3A INZ('END') C WRITE QSYSPRT REC


This prints `ABCXY   END`, identical to the free-format form - a subfield
declared on a D-spec lays out exactly as one declared with `DCL-SUBF`, and a
fixed-format alpha subfield carries no length prefix unless it is declared
`VARYING`.

> Printer output driven by the program cycle and O-specs (see the
> [Fixed-Logic Program Cycle](/docs/triton-rpg/fixed-logic-program-cycle/)
> and `EXCEPT`) uses a separate overflow mechanism from the `WRITE`-with-source-record
> form described here. Both forms are available in either source format.