Skip to content

SERPRINT - SYSOUT Compression Facility

ChangeMan ZMF has a facility that makes it possible to eliminate the paper printing and subsequent storage, and access and traceability problems of any application's SYSOUT listings. This facility gathers files destined to SYSOUT queues, concatenates them, and compresses them into a single component of a PDS. You can use this facility regardless of whether or not your shop has converted to ChangeMan ZMF.

Each listing data set normally queued to a SYSOUT class is redirected to a temporary file with accurate DCB attributes and adequate disk space to hold it. The recommended DSNAME of each passed file is &&LISTxxx, where LIST could be some other recognizable character string but LIST is very meaningful. For example:


could be converted to:

//              UNIT=SYSDA,SPACE=(CYL,(1,2),RLSE),
//              DCB=(RECFM=FBA,LRECL=121,BLKSIZE=2420)
//* or          DCB=(RECFM=VBM,BLKSIZE=4088)


There could be multiple converted SYSOUT definitions per job step. The only restriction is that each temporary DSNAME must start with the same character string (LIST) and suffixed with an alphanumeric string that makes it unique within the job. It is further recommended that the suffix be at least two numeric digits in ascending order with adequate spacing to keep it manageable. The DCB attributes of each passed file are independent of one another.

Since SERPRINT is unable to handle VIO data sets, it is required that the files are allocated on non-VIO devices. To accommodate this requirement, a new variable, DEFAULT NON-VIO UNIT NAME has been added to Global Admin panel CMNGGP01. Make sure your SYSPROG/STORAGE ADMIN has designated this UNIT for NON-VIO usage.

The gathering and concatenation of each file is done by component SERPRINT. For example:

//              PARM=('INDSN(LIST*)',
//              'OUTFILE(PRINT1,PRINT2)')
//              UNIT=SYSDA,SPACE=(CYL,(5,5),RLSE),
//              DCB=(RECFM=VBM,LRECL=133,BLKSIZE=23476)


The specification of COND=EVEN is important. Before, when spooling directly to a SYSOUT queue, you could see all that had been spooled up to the point of any surprising ABEND. With this facility, those passed file contents can only be viewed by SERPRINT's post-processing capabilities and any previous step that ABENDs would normally flush this step unless COND=EVEN has been specified.

The PARM is critical. It dictates the input file structure to search for and the output file or files to put the concatenation out to. There are two forms for input file structure:

// PARM=('INDSN(LIST*)',...



The use of INFILE is not recommended as it refers to procedure step names and DDNAMEs which is rather inflexible. The recommended approach is to use INDSN, which dictates the low order node prefix structure to search for. The searching process involves the Scheduler Work Area (SWA) Manager above or below the XA line. Each discovered file is read and each record is converted to VBM - variable blocked machine control characters with trailing blanks truncated.

Each output file DDNAME is specified by the keyword OUTFILE in the PARM. In the recommended example above, DDNAMEs PRINT1 and PRINT2 are targets for the concatenated output. PRINT1 is passed as a sequential file to be compressed. PRINT2 is written directly to a SYSOUT queue for browsing and potential redirection to paper listing or deletion. Each concatenated file is preceded by a banner detailing where it came from. For example:

DDNAME: procstep.stepname.ddname

As suggested above, procstep is the step name (if any) that invoked the procedure; stepname is the actual step name within the JCL stream that invoked a program that wrote to DDNAME ddname. A trailing statistics record is written detailing records and bytes used. For example:

<STATS: RECS=nnnn BYTES=nnnnnnn>

The output file that is passed (in this case, PRINT1) is targeted for input to component SERCOPY. The example that follows is in Skeleton notation but could be modified slightly to use symbolic substitution in a cataloged procedure:



The PARM dictates that a compress (COMP) is to be performed using file SYSUT1 as input, file SYSUT2 as output, and whatever component name substitution for &CMPNAME is file tailored. If the component already exists in the output library, it is replaced by the new one coming in. If an x37 ABEND occurs, it is intercepted internally, an IEBCOPY compress is invoked on the output library, and the compression is re-initiated. If another x37 ABEND occurs, the output library is dynamically reallocated with larger dimensions elsewhere and the compression re-initiated. Without the REALLOC keyword, no reallocation is attempted.

Beginning with release 4.1.0, the calculation method of determining the compression ratio, displayed at the end of a decompressed listing, has been changed.

The formula for calculation of compression percentage follows:

C = (T1 - T2) / T1 *100
C = compression percentage
T1 = bytes full
T2 = bytes compressed


If T1 is 1,000,000 bytes and T2 is 600,000 bytes, we get:

(1,000,000 - 600,000) / 1,000,000 = 40% compression.

In the previous compression routine, using the Huffman algorithm, number of bytes full (T1) was passed using the largest possible size of each record read BEFORE truncating to ragged right.

T1 is used as the summation of bytes into SERCOPY which already has had considerable white space stripped off - often 30%.

The only real statistic that counts is how much space is saved on the disk pack.


Alg=2 garners compression is nearly as good as the old Huffman algorithm but without the overhead of having to pass the entire file twice. The full expansion to VBM means to ragged right. Formerly, the compression statistics appended to the listing expansion were based on the full number of bytes of the flat right listing concatenation. Now compression is more accurate in that it is based on the actual number of ragged right byte summation.

Browsing Compressed Listings

The ability to browse a compressed listing is implicit within ChangeMan ZMF but can also be used outside by either a specialized CLIST or submitted batch job to decompress the component and subsequently browsing the sequential data set. We deliver a CLIST called CMNBRWCL and associated panels to perform just such a function. It is the user's responsibility to incorporate this ability into their ISPF panel mechanism. You can however simply (from within a ChangeMan ZMF session) use the command TSO %CMNBRWCL and the selection panel CMNLSTB0 will display. Supply the Dataset and Member and you can see the decompressed listing:

CMNLSTB0                    Browse Compressed Listing
Command ===>

Compressed listing library:

Dataset . . . . CMNTP.S6.COMM.STG6.#000001.LST
Member . . . .  COMSRS00    (blank for member selection list)


Also note that at the bottom of the decompressed file are statistics within banners detailing the amount of compression attained. The calculation is based on the actual number of bytes needed to hold the compressed file divided by the number of bytes in the composite decompressed file(s). For example:

* Compression Statistics             *
*                                    *
* Number of records: 494             *
* Bytes expanded: 36,552             *
* Bytes compressed: 8,240            *
* Compression ratio: 77.46%          *


There are other vendor products for storing listings on line but they do not discern which is the latest or the one that corresponds to what you have executed in production. Any kind of file that can be sent to a SYSOUT spooling can be incorporated with this mechanism.