|
In addition to the coding conventions, consider the following when
writing your own output writing routine: - Obtaining Storage for Work Areas: Using
the GETMAIN or STORAGE macro, the output writing routine should obtain
storage in which to set up switches and save record lengths and control
characters.
- Processing an Input Data Set: To process
a data set, the writing routine must get each record individually
from the input data set, transform (if necessary) the record format
and the control characters to conform to the output data set's
requirements, and put the record in the output data set. Consider
each of these tasks individually:
- Before the routine actually obtains a record from an input data
set, the routine must provide a way to handle the two forms of record
control character that are allowed in an output data set, if the output
device is a printer.
Most printers are designed so that, if the
output data set records contain machine control characters, a record
(line) is printed before the effect of its control character is considered.
However, if ANSI control characters are used in the output records,
the control character's effect is considered before the printer
prints the line. Thus, if the input data sets do not all have the
same type of control characters, you will need to avoid overprinting
the last line of one data set with the first line of the next.
When
the input records have machine control characters and the output records
are to have ANSI control characters, the standard (IBM-supplied) output
writing routine produces a control character that indicates one line
should be skipped before printing the first line of output data.
When
the input records have ANSI control characters and the output records
are to have machine control characters, the standard writing routine
prints a line of blanks before printing the first actual output data
set record. Following this line of blanks, the printer generates a
one-line space before printing the first record.
Depending
upon the characteristics of the printers in your installation, you
will probably want your output writer to perform some kind of “printer
initialization” like that outlined here.
- After the output writing routine has properly opened the input
data set and has completed any necessary printer initialization, it
must obtain records from the input data set.
The standard output
writing routine uses the locate mode of the GET macro. If you use
this macro, you will need to check the MACRF field of the input data
set's DCB to see if GET in locate mode is allowed. If not, you
can override the MACRF parameter on the GET macro itself. See z/OS DFSMSdfp Advanced Services for information on coding and using all the QSAM macros.
In a JES2 system, the padding is done automatically.
In a JES3
system, if blank truncation is in effect (TRUNC=YES specified on the
BUFFER initialization statement or the SYSOUT initialization statement),
then fixed format records will not be padded with blanks. You need
to do the padding manually.
- Having obtained a record from the input data set, the output writing
routine must now make sure that its format and control character are
compatible with the requirements of the output data set.
Because
the output data set is already opened when the output writing routine
is entered, your routine will have to adhere to the established conventions.
The standard output writing routine uses the PUT macro in
the locate mode to write records to the output data set. For fixed-length
output, it obtains the record length for the output data set from
the DCBLRECL field of the DCB.
If an input record is longer
than the length specified for the output records, the standard output
writing routine truncates the input record from the right.
If
an input record is shorter than the length specified for the output
records, the standard output writer left-justifies the input record
and pads the field with blanks.
When the output record length
is variable and the input record length is fixed, the standard output
writer adds control character information (if necessary) and variable
record control information to the output record. Control character
information is one byte, and record control information is four bytes
long. Both additions are at the high-order end of the record.
If
the output record is not at least 18 bytes long, the standard output
writer pads it on the right with blanks. The standard output writer
also adjusts the length of the output record to match the length of
the output buffer.
- When the output writing routine has successfully adjusted the
input and output records, it can read the input data set until end
of data. At that point, you need to consider another aspect of input
data set processing: what is going to happen to the last input record?
The standard output writer handles output to either card punch or
printer, as required; your routine could also send output to an intermediate
tape or DASD device. Depending upon the kind of device, the last few
records obtained from the input data set will receive different treatment.
It might happen that all the records from a given data set
are not available on the output device until the output of records
from the next data set is started, or until the output data set is
closed. However, if you specify CERTIFY=Y as a start-up parameter,
the records can be made available on the output device after all the
input records have been written by the output writing routine. When
the output data set is closed, the standard output writer automatically
puts out the last record of its last input data set.
For Punch Output: When a card punch is the output
device, the last three output cards could still be in the machine
when the input data set is closed.
To put out these three records
with the rest of the data set, and with no breaks, the standard output
writer provides for three blank records following the actual data
set records.
For Printer Output: When
a printer is the output device, the last record of the input data
set is not normally put in the output data set at the time the input
data set is closed.
To force out this last record, the standard
output writer generates a blank record to follow the last record of
the actual data set.
- Using the CERTIFY Function: The CERTIFY
function can be specified as a parameter when starting the external
writer. It guarantees that data will not be lost when an abend condition
occurs. If the CERTIFY function is not enabled, it is possible that
records written to the QSAM buffers, but not yet written to the output
device, can be purged before they are recorded during an abend situation.
This is possible, for example, when the output data set is not large
enough to contain the data, resulting in an ’end-of-volume’
(x37) abend.
The CERTIFY function flushes the buffers
each time an input data set is processed, and makes that data available
on the output device. However, while guaranteeing data integrity,
this function might also increase processing overhead and decrease
efficient output data set space utilization. Also, note that even
with CERTIFY=Y, data integrity might be compromised in the case of
writing multiple JES data sets to a partitioned dataset (PDS) or PDSE
in an abend situation.
If you need to use the CERTIFY function,
you need to modify your output writing routine to be similar to that
supplied by IBM. Refer to module IEFSD087 for an example of how to
enable the CERTIFY function. Basically, you must do the following: - In the external writer main task, force the number of buffers
for the output data set to 1. That is, set DCBBUFNO=1.
- In the output writing routine after all records are PUT to the
data set, perform a second PUT to write a blank line (a ‘transition
record’) after the data to separate the data sets.
- In the output writing routine, commit the data to the output device.
- Closing Input Data Set(s): After the standard
output writer finishes putting out the records of an input data set,
it closes the data set before returning control to the calling module.
All input data sets must be closed.
After closing the input data
set, it is recommended that your output writer free the buffer pool
associated with the input data set (by issuing the FREEPOOL macro).
- Releasing Main Storage: The output writing
routine should release the storage it acquired, using the FREEMAIN
or STORAGE macro, before returning to its caller.
- Handling Errors: The routine must put a
return code into register 15 before returning to its caller using
the RETURN macro.
The standard output writer sets a return code
of 8 if it terminates because of an unrecoverable error on the output
data set; otherwise, the return code is 0. The output writing routine
must handle input errors itself.
|