PIPE$ 1R2A - Piping Processor Output to an Alternate File
PIPE$ is a routine that allows a processor to redirect its output to a print alternate file. It consists of an omnibus definition element and a relocatable subroutine, and can be incorporated into existing MASM programs with few changes.
PIPE$ works by intercepting the ERs to PRINT$, APRINT$, SYMB$ (W$ to PRINT$), EXIT$, and ERR$. If piping is active, it will reroute printing commands to an alternate file. EXIT$ and ERR$ are intercepted to close out the file at program termination.
To preempt interception for an individual ER, code a 0 subfield after the name, as in " ER PRINT$,0 ".
The PIPE$ initializing routine uses registers X11, A0-A3, and R1, and calls EDIT$. The PIPE$ ER intercept routines preserve all registers.
The initializing routine should be called fairly early in the program, after reading INFOR$ but before signing on and doing any preliminary file setup, assigns, etc.
There are two methods of implementing piping in a program. Each is discussed in the sections that follow.
This method will allow piping to be invoked at the time the processor is called. To incorporate this method, follow these steps:
1) Add the statement " $INCLUDE 'PIPE$DEF' " to each element that may have any of the intercepted ERs, and to the element from which you will initialize piping. This will define the proc ER as well as the initializing proc.
2) Since PIPE$ is intended for processors, it is assumed that the program will read the INFOR$ table on entry. The address of that table must be supplied in the following code, which should be placed right after the INFOR$ read:
PIPE$INIT[,'option'] INFOR-TABLE ['temp-name','cat-name'] [+words,entry-point] . One or more mod words
The only option recognized in this call is 'M', to display a message when piping is successfully opened. If 'M' is not used, the PRINT$ word for the message is available for use later at PIPE$MSG.
The basic names for temporary and catalogued piping files may be supplied. The temporary name may be 1-10 characters; it will be truncated if longer. Successive piped calls within the same run will append sequence numbers of 01, 02, etc, wrapping around after 99. The name temp-name$T will always be attached to the most recent temporary file.
The catalogued name may be 1-12 characters. This file will always be cycled. If the name is less than 7 characters, the user's generated runid will be appended.
If not supplied, the default names are $PIPE$FILE and PIPFL$.
One or more optional modification parameter words may follow the LMJ call. These may be used in the case of relocatables that will be included in the program, which may have intercepted ERs but for which there is no source. PIPE$ will search from the entry point through the given number of words and replace any of the intercepted ERs with the appropriate SLJ. The maximum word count is 4095. These relocatables must be collected in a writeable bank. Example: +25,EPRINT$.
PIPE$DEF also defines some cells in the two-word external tag PIPE$FLAGS. These cells may be tested, set, or cleared by the user and have the following meanings if non-zero:
PIPE$ACTV - Piping is active. This cell may be temporarily cleared and later set to avoid piping one or more print lines. It must be set before program exit to ensure proper file closeout.
PIPE$LVOP - The pipe file is to be left open and un-@BRKPTed at end.
PIPE$REUS - Reuse an existing pipe file if the name $PIPE$FILE$ is attached.
PIPE$CATF - The pipe file is catalogued vs. temporary.
PIPE$LIST - Output is to go to standard print as well as the pipe file. This is handled transparently, but the program may find this information useful in certain cases, such as deciding whether to pause during demand output. This cell may be set or cleared at will during execution to display or suppress selected lines from standard print.
PIPE$FNCC - Character count of edited Fieldata pipe filename at PIPE$FILENM.
PIPE$TRAC - CSF$ tracing is active.
PIPE$MAXW - The pipe file print width is to be expanded to 2047 words.
PIPE$NSTW - Do not automatically expand standard print width if PIPE$MAXW and PIPE$LIST are both set. This might be needed if the program already handles setting and resetting standard print width.
PIPE$EMSG - Print an end message when the pipe file is closed. This can be useful if print also goes to standard output and causes the initial piping message to scroll off the screen.
PIPE$IMSG - Display initial message when opening pipe file. This option is set through the M option on the PIPE$INIT call, but may later be set or cleared by the user if a pipe file is reopened in the same call.
3) When @MAPping the program, include the PIPE$ relocatable. $(1) of PIPE$ may be overlayed after the initial call; $(0) and $(2) must remain visible.
Once a processor has been compiled with PIPE$, piping is activated by using the element cycle field of the processor call command. This field may contain a special character and/or options digits. The digits represent several options that be combined by ORing them as octal values. The general format of a processor call using piping is as follows:
Note that the "(piping)" field comes BEFORE the comma separating any options. Valid piping fields are as follows:
@MYPROG(0) - Redirect program output to a temporary file. Files are named starting at temp-name01 and go up to temp-name99 before wrapping around to 01. At program termination the file is @BRKPTed. The name temp-name$T is always left attached to the most recent temporary file for easy reference.
@MYPROG(1) - Redirect output to a catalogued file. PIPE$ catalogues the +1 cycle of file cat-nameRunid, similar to the way the utility BK1 catalogues BKFIL$Runid(+1). At program termination the file is @BRKPTed and @FREEd.
@MYPROG(+0) - Redirect program output to a temporary file and also to standard output.
@MYPROG(+1) - Same as (+0) when piping to a catalogued file.
@MYPROG(2) - Do not @BRKPT or @FREE,A the pipe file at program termination.
@MYPROG(4) - Reuse a pipe file left open by a (2) call. The @USE name $PIPE$FILE$ is attached to a file while piping is active. This name is normally released when the program ends unless the (2) call is used.
If desired, the name may be attached to any file prior to a (4) call, and output will be directed to that file.
@MYPROG(6) - Reuse a file and do not @BRKPT or @FREE it at termination (2 & 4 ORed). Note how the sequence of a (2) call, followed by one or more (6) calls, and finally a (4) call, can be used to stack the output of several programs in a single file.
The above three examples may also specify using a catalogued file -- (2) becomes (3), (4)->(5), etc. -- and/or listing the output: (+2), (+3), ...
The 10 option may be ORed with any of the above to force expansion of the maximum width of the PIPE$ print alternate file to 2047 words. If the "+" is present, the standard print width will also be expanded unless 20 is ORed with the options digits; it will be reset on exit unless the file is being left open, as in @MYPROG(+12).
The 40 option may be ORed with any of the above to activate CSF$ tracing:
@MYPROG(40) - Same as (0), but turn on CSF$ tracing.
@MYPROG(+45) - Same as (+15), but turn on CSF$ tracing.
Finally, there are two calls for special cases. The actions triggered by these calls are performed when PIPE$INIT is called, following which the program exits with no further action taken.
@MYPROG(-) - This call format tells the program to @FREE all temporary piping files. It is provided as a convenience, since up to 99 such files may be assigned during a run.
@MYPROG(+) - This call may be used if a program aborts while a pipe file is open. Since the program did not have a chance to EXIT$ or even ERR$, the pipe file was not closed and does not have a proper end of file. This call will @BRKPT the file and close it. (The MORE utility can accomplish the same thing with the B option, but this call will also release the internal name.)
This method allows the program to initiate piping based on its own internal criteria rather than through the processor call. The setup differs in Step 2:
1) Add the statement " $INCLUDE 'PIPE$DEF' " to affected elements, as before.
2) Initialize piping as follows:
PIPE$INIT 'options' ['temp-name','cat-name'] . [+words,entry-point] . Optional mod words
Note that the option string is in the first field rather than following the proc name. Options correspond to the various processor call initiated formats described in the last section, and are as follows:
C - Use catalogued vs. temporary file.
E - Display end message when closing the pipe file.
L - List output to standard print as well as pipe file.
M - Display initial piping message.
N - Do not set or reset standard print width if both L & W set.
O - Leave pipe file open and un@BRKPTed at end of program.
R - Reuse existing pipe file if $PIPE$FILE$ name attached.
T - Use temporary vs. catalogued file.
W - Expand pipe file max width to 2047 words. If the L option is set,
also expand standard print width.
$ - Turn on CSF$ tracing.
The PRINT$ word for the initial message is at external tag PIPE$MSG, in case the program decides to use it at a later time. The complete edited Fieldata filename of the pipe file is at PIPE$FILENM, and its character count is placed in the PIPE$FNCC cell after piping is opened. The FITEM$ packet used for the pipe file is at PIPE$FITMPK.
CSF$ tracing may be enabled or disabled by setting or clearing PIPE$TRAC.
3) @MAP program with PIPE$ relocatable.
For program-initiated piping, the routine PIPECLOSE$ may be called using LMJ X11 to close the current pipe file. If the PIPE$EMSG cell is set, an end closing message will be displayed. PIPECLOSE$ uses X11, A0-A3.
After the file has been closed, the next one may be opened by calling PIPE$INIT again. If PIPECLOSE$ is used, all location counters of PIPE$ must remain visible.
Programs that use FUSION may employ piping by observing the following:
1. The $INCLUDE of 'PIPE$DEF' must come AFTER the $INCLUDE of 'FUSION$DEF'.
2. The program must not generate any FCCs, as these would go into the alternate print file and be viewed as garbage characters. FUSION 2R3 has two new utility procedures, FU$FCCSU and FU$FCCRE, that can be used to suspend and resume FCC capability. When it is suspended, any commands to generate FCCs will be ignored, so no existing code has to be changed.