Trailing-Edge
-
PDP-10 Archives
-
DEC_CMS-20_V1.0_SRC
-
cms/sources/resfil.bli
There are no other files named resfil.bli in the archive.
MODULE RESFIL (
IDENT = '1',
%IF
%BLISS(BLISS32)
%THEN
LANGUAGE(BLISS32),
ADDRESSING_MODE(EXTERNAL=LONG_RELATIVE,
NONEXTERNAL=LONG_RELATIVE)
%ELSE
LANGUAGE(BLISS36)
%FI
) =
BEGIN
!
! COPYRIGHT (C) 1982, 1983 BY
! DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
!
! THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
! ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
! INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
! COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
! OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
! TRANSFERRED.
!
! THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
! AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
! CORPORATION.
!
! DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
! SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
!
!++
! FACILITY: CMS Library Processor
!
! ABSTRACT:
!
! Get a file from the specified library and place it in the user's
! area along with any corrections or changes that are current.
!
! ENVIRONMENT: VAX/VMS, DS-20
!
! AUTHOR: D. Knight , CREATION DATE: 20-Nov-78
!
!--
!++
! General Description
!
! RESFIL is called by RESERVE to process the actual text for FETCH,
! RESERVE, ANNOTATE and the merge function. RESERVE and FETCH are
! handled identically, the text is simply delivered to the user's
! working area. ANNOTATE and merge have the text modified. ANNOTATE
! adds the generation numbers of each line and formats the text in
! a listable format. The merge function simply places the
! generation number on each line as required.
!
! File structures
!
! As described in RESERVE.
!
!--
!
! TABLE OF CONTENTS
!
FORWARD ROUTINE
RESFIL, !Top level control loop
GET_LIN, !Get a line of text from the file in the library
HDR: NOVALUE, !Output an ANNOTATE header line
OUTTXT : NOVALUE, !Output text (open output file if needed)
SETINP : NOVALUE, !Set up the input file to be used
SETOUT : NOVALUE, !Set up the output file to be used
TERMINATE: NOVALUE, !Close all files
WRT_LINE: NOVALUE; !Output a line (include any source annotations)
!
! INCLUDE FILES:
!
%if
%bliss(bliss32)
%then
library 'sys$library:starlet';
%else
require 'jsys:';
%fi
LIBRARY 'XPORT:';
REQUIRE 'SCONFG:';
REQUIRE 'BLISSX:';
REQUIRE 'COMUSR:';
REQUIRE 'HOSUSR:';
!
! MACROS:
!
MACRO
IOB$H_RESULTANT=$SUB_FIELD(IOB$T_RESULTANT,STR$H_LENGTH) %,
IOB$A_RESULTANT=$SUB_FIELD(IOB$T_RESULTANT,STR$A_POINTER) %,
STG(L,M) = OUTTXT(CH$PTR(UPLIT(L)),%CHARCOUNT(L),M) %;
!
! EQUATED SYMBOLS:
!
GLOBAL LITERAL
MAX_LINES=57; !Page size - 3
!
! OWN STORAGE:
!
GLOBAL
L_CNTR ; !Line counter used by HDR
OWN
FIL_LEN,
FIL_PTR,
FIRST_CALL : INITIAL(0),
$IO_BLOCK(INPUT), !Input file IOB
I_OPN, !Input file is open
O_OPN, !Output file is open
PAG_NUM, !Holds the current page number
S_L_PTR,
SEQ_FLG, !TRUE if sequenced file is to be produced
!FALSE if not.
SEQ_SEEN; !TRUE if actual sequence numbers seen
!FALSE if not
!
! EXTERNAL REFERENCES:
!
external literal
s_invcksum, !CRC's don't match
s_isthere, !file already exists
s_nocksum, !No CRC detected
s_onoopen, !cannot open output file
s_useverrec; !use verify/recover
!Merge control
EXTERNAL
MERGE,
MRG_BRNCH,
MRG_MAIN,
NO_MRG;
EXTERNAL
CHRLEN, !Length of chronology string
CHRONO, !Chronology flag
CMD, !Which command
FETSTS, ! Status to indicate special completion
! typically in the case of a warning
! or alternate success
f_perf_crc, ! Perform CRC calculation if true ( In OUTSTG, else ignore)
LGEN, !Current generation of the line
LGEN_L, !Length of current generation
MAX_G_LGT, !Maximum possible generation length
NAME_PTR,
NAME_SIZ,
NOTES, !Source annotation flag
NOTLEN, !Source audit pattern string length
ONPATH, !Current operation is on correct generation path
OUTPUT_IOB : $XPO_IOB(),
PAT_FIL, !Left margin fill count
PAT_GEN, !True if generation is needed in audit mark
PAT_LS, !Left part of pattern
PAT_LLS, !Length of left part
PATPOS, !Position in line, 0 = left margin
PAT_RS, !Right part of pattern
PAT_LRS, !Length of right part
PLUS_GET, !Plus operator appeared in normal generation expression
PLUS_MRG; !Plus operator appeared in merge generation expression
EXTERNAL ROUTINE
aschex, !Convert ASCII to hex
BADLIB,
BADXPO,
BUG,
BYE, !Exit with message
CHKGEN,
CMPGEN,
crccalc,
crctable,
DATTIM,
DECASC, !Convert decimal to ASCII
ERSXPO,
GEN_SETUP,
GET_LXM, !Get text lexeme
GET_MLINE,
NATEQL, ! Check name and type of file spec
OUTNUM,
OUTNMZ, !Output numeric filled value
OUTSTG,
PAT_SETUP,
say,
sysmsg,
test_gen, !check for common ancestor generation
VERNUM ;
GLOBAL ROUTINE RESFIL (FIL_NAM_LGT,FIL_NAM_STR,G_LEN,G_PTR) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Generate a new file from the master file and a list of corrections.
!
! FORMAL PARAMETERS:
!
! FIL_NAM_LGT - length of file name to be processed
! FIL_NAM_STR - pointer to file name to be processed
! G_LEN - length of generation to be retrieved
! G_PTR - pointer to generation to be retrieved
!
! IMPLICIT INPUTS:
!
! NONE.
!
! IMPLICIT OUTPUTS:
!
! NONE.
!
! ROUTINE VALUE:
! COMPLETION CODES:
!
! TRUE - success
! FALSE - failure
!
! SIDE EFFECTS:
!
! NONE.
!
!--
BEGIN
LOCAL
count,
CUR_DEL : VECTOR[CH$ALLOCATION(50)],
CUR_DEL_LEN,
CUR_DEL_FLG,
found_crc ,
GEN_BUF : VECTOR[CH$ALLOCATION(50)],
GEN_LGT,
KEEP,
LIN_NUM,
SEQ_N,
total,
TEXT_SEEN;
FIL_LEN=.FIL_NAM_LGT;
FIL_PTR=.FIL_NAM_STR;
!This is done to make sure any errors are reported as user errors
!only for the first file of an element. If errors occur after the
!first, they ARE bugs or errors in the library.
FIRST_CALL=.FIRST_CALL+1;
!Assume sequencing is off
SEQ_FLG=FALSE;
SEQ_SEEN=FALSE;
!First text line has not yet been seen (don't include header lines)
TEXT_SEEN=FALSE;
!Point to generation information
CH$MOVE(.G_LEN,.G_PTR,CH$PTR(GEN_BUF));
GEN_LGT=.G_LEN;
!Open input file (the output file opening must be postponed
!until we know whether sequencing is to be performed)
SETINP();
!No output file yet
O_OPN=FALSE;
!Default line number to be printed on annotated listing
LIN_NUM=0;
SEQ_N=0;
!The page number starts with one
PAG_NUM=1;
!No deletion mark has yet been postponed
CUR_DEL_FLG=FALSE;
!Initialize generation stack
GEN_SETUP(KEEP);
!Set up source file pattern
PAT_SETUP();
! Zero CRC accumulators
count = 0;
total = 0;
found_crc = false;
! Tell OUTSTG not to calculate CRC if called from here
f_perf_crc = false;
! Setup CRC polynomial table
crctable();
!Now process the complete file
REPEAT
BEGIN
LOCAL
comp,
S_SIZ,
crc_count,
TAG;
!Read a line
s_siz = get_lin();
! Calculate the crc of the line (if we haven't hit EOF)
! But first see if this is the CRC line itself
if .s_siz neq eof
then
begin
IF
ch$eql(4,ch$ptr(uplit('*/C:')),4,.s_l_ptr)
then
begin
found_crc = true ;
if .merge neq mrg_brnch
then
begin
local
len,
ptr;
len = .s_siz - 4 ;
ptr = ch$plus(.s_l_ptr, 4);
crc_count = aschex(ptr, len) ;
s_siz = eof;
end
else
s_siz = eof
end
else
if .merge neq mrg_brnch
then
begin
count = 0;
count = crccalc(.s_siz, .s_l_ptr);
total = .total + .count;
end ;
end ;
!Quit at end of file
IF
.s_siz eql eof
THEN
BEGIN
!If no output file is open yet, open it.
!This makes sure that if the user gave us a
!zero length file, he will get back a zero length file
!if he asks for it again.
IF
NOT .O_OPN
THEN
SETOUT();
!Output the postponed deletion, if any
IF
.CUR_DEL_FLG
THEN
BEGIN
if
test_gen(ch$ptr(cur_del),.cur_del_len)
then
!don't output the deletion unless it is the
! descendant of the common ancestor generation
begin
STG('*',FALSE);
OUTTXT(CH$PTR(CUR_DEL),.CUR_DEL_LEN,FALSE);
STG(' ',TRUE)
end
END;
if not .found_crc
then
sysmsg(s_nocksum,cat((.fil_len,.fil_ptr),
' has no checksum'),0)
else
if .crc_count neq .total
and .merge neq mrg_brnch
then
sysmsg(s_invcksum,cat((.fil_len,.fil_ptr),
' has an invalid checksum'),0);
TERMINATE();
RETURN G_OK
END;
!Get tag character
TAG=CH$RCHAR_A(S_L_PTR);
S_SIZ=.S_SIZ-1;
!See if it is a control command
IF
.TAG EQL %C'*'
THEN
!Command
BEGIN
!See if there is a master control record
!For now it is only necessary to check for a /S,
!meaning sequencing is in effect.
IF
CH$EQL(2,CH$PTR(UPLIT('/S')),.S_SIZ,.S_L_PTR)
THEN
!Sequencing is in effect
BEGIN
IF
.TEXT_SEEN
THEN
!Cannot handle a file which is half-sequenced
!The /S must be before ANY text.
BADLIB(LIT('/S is out of order'));
SEQ_FLG=TRUE
END
ELSE
CHKGEN(S_L_PTR,.S_SIZ,KEEP,CH$PTR(GEN_BUF),.GEN_LGT)
END
ELSE
!A data line has a blank control character
!Output the line without the blank
IF
.TAG EQL %C' '
THEN
!Data line
BEGIN
TEXT_SEEN=TRUE;
IF
.KEEP
THEN
BEGIN
!Get the line number and the text separated
IF
.SEQ_FLG
THEN
BEGIN
!Get the line and its sequence number
SEQ_N=GET_MLINE(.G_LEN,.G_PTR,S_L_PTR,S_SIZ);
!If the line number is non-zero, the generation is sequenced
IF
.SEQ_N NEQ -1
THEN
SEQ_SEEN=TRUE;
END;
IF
.CMD EQL K_ANNOTATE_COM OR
.MERGE NEQ NO_MRG
THEN
BEGIN
!Output the postponed deletion, if any
!and if it is not a simple replace
IF
.CUR_DEL_FLG AND
CH$NEQ(.CUR_DEL_LEN,CH$PTR(CUR_DEL),.LGEN_L,.LGEN)
THEN
BEGIN
if
test_gen(ch$ptr(cur_del),.cur_del_len)
then
!don't output the deletion unless it is the
! descendant of the common ancestor generation
begin
STG('*',FALSE);
OUTTXT(CH$PTR(CUR_DEL),.CUR_DEL_LEN,FALSE);
STG(' ',TRUE)
end
END;
CUR_DEL_FLG=FALSE;
IF
.CMD EQL K_ANNOTATE_COM
THEN
BEGIN
IF
CH$RCHAR(.S_L_PTR) EQL FORM_FEED AND
.S_SIZ EQL 1
THEN
BEGIN
PAG_NUM=.PAG_NUM+1;
!Tell user about break
IF
.LGEN_L NEQ 0
THEN
OUTTXT(.LGEN,.LGEN_L,FALSE);
!Advance line number for unsequenced file
IF
NOT .SEQ_SEEN
THEN
LIN_NUM=.LIN_NUM+1;
STG(' <PAGE>',TRUE);
HDR(.NAME_PTR,.NAME_SIZ,.FIL_NAM_STR,.FIL_NAM_LGT)
END
ELSE
BEGIN
LOCAL
SEQ_BUF : VECTOR[CH$ALLOCATION(SEQ_NUM_SIZE)],
SEQ_LEN;
!See if enough room is on the page
IF
.L_CNTR GEQ MAX_LINES
THEN
HDR(.NAME_PTR,.NAME_SIZ,.FIL_NAM_STR,.FIL_NAM_LGT);
IF
.LGEN_L NEQ 0
THEN
OUTTXT(.LGEN,.LGEN_L,FALSE);
STG(' ',FALSE);
IF
NOT .SEQ_SEEN
THEN
!Unsequenced file, put out simple line number
BEGIN
LIN_NUM=.LIN_NUM+1;
OUTNUM(.LIN_NUM,FALSE)
END
ELSE
!Generate zero filled value for sequenced file
OUTNMZ(.SEQ_N,SEQ_NUM_SIZE,FALSE);
STG(' ',FALSE);
!Now output the line proper
L_CNTR=.L_CNTR+1;
OUTTXT(.S_L_PTR,.S_SIZ,TRUE)
END
END
ELSE
BEGIN
!Put out the generation expression if non-zero
IF
.LGEN_L NEQ 0
THEN
begin
if
test_gen(.lgen,.lgen_l)
then
!don't put out the generation value unless
! it is the descendant of the common ancestor,
! since any generation at the common ancestor
! or before is treated the same
OUTTXT(.LGEN,.LGEN_L,FALSE)
end;
STG(' ',FALSE);
OUTPUT_IOB[IOB$G_SEQ_NUMB]=.SEQ_N;
OUTTXT(.S_L_PTR,.S_SIZ,TRUE)
END
END
ELSE
BEGIN
OUTPUT_IOB[IOB$G_SEQ_NUMB]=.SEQ_N;
WRT_LINE(.S_SIZ,.S_L_PTR)
END
END
ELSE
!See if this deletion is occurring during a merge
BEGIN
IF
.MERGE NEQ NO_MRG AND
.ONPATH
THEN
!Mark the deletion
BEGIN
IF
NOT .CUR_DEL_FLG
THEN
!No postponed entries yet
BEGIN
CH$MOVE(.LGEN_L,.LGEN,CH$PTR(CUR_DEL));
CUR_DEL_LEN=.LGEN_L;
CUR_DEL_FLG=TRUE
END
ELSE
IF
CH$NEQ(.LGEN_L,.LGEN,.CUR_DEL_LEN,CH$PTR(CUR_DEL))
THEN
!Postponed entry doesn't match current entry
BEGIN
if
test_gen(ch$ptr(cur_del),.cur_del_len)
then
!don't put out a deletion for any
! generation at the common ancestor
! or before, since later generations
! are the only ones that are significant
begin
STG('*',FALSE);
OUTTXT(CH$PTR(CUR_DEL),.CUR_DEL_LEN,FALSE);
STG(' ',TRUE)
end;
!Now postpone the new one
CH$MOVE(.LGEN_L,.LGEN,CH$PTR(CUR_DEL));
CUR_DEL_LEN=.LGEN_L
END
END
END
END
ELSE
!Anything left over in column 1 other than "+" is an error
IF
.TAG NEQ %C'+'
THEN
!Error
BADLIB(LIT('Illegal control record'));
!Comment lines (+) are discarded automatically
END;
!Just in case
BUG(LIT('Cannot get here (RESFIL)'))
END; !End of RESFIL
ROUTINE GET_LIN =
!++
! FUNCTIONAL DESCRIPTION:
!
! Get a source line
!
! FORMAL PARAMETERS:
!
! NONE.
!
! IMPLICIT INPUTS:
!
! The input file is already open.
!
! IMPLICIT OUTPUTS:
!
! S_L_PTR - Character pointer to start of line
!
! ROUTINE VALUE:
! COMPLETION CODES:
!
! length of line, -1 if EOF.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
BEGIN
LOCAL
COMP;
!Get a line of input and the completion value
COMP=$step_get(IOB=INPUT_IOB,FAILURE=0);
!Point to the line
S_L_PTR=.INPUT_IOB[IOB$A_STRING];
IF
.COMP
THEN
.INPUT_IOB[IOB$H_STRING]
ELSE
-1
END; !End of GET_LIN
GLOBAL ROUTINE HDR (ELM_PTR,ELM_LGT,FIL_PTR,FIL_LGT) : NOVALUE =
!++
! FUNCTIONAL DESCRIPTION:
!
! Output a page header
!
! FORMAL PARAMETERS:
!
! ELM_PTR - pointer to element name
! ELM_LGT - length of element name
! FIL_PTR - pointer to file name
! FIL_LGT - length of file name
!
! IMPLICIT INPUTS:
!
! NONE.
!
! IMPLICIT OUTPUTS:
!
! NONE.
!
! ROUTINE VALUE:
! COMPLETION CODES:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
BEGIN
LOCAL
DBUF : VECTOR[CH$ALLOCATION(40)],
DLGT;
L_CNTR=0;
!Put out header
OUTTXT(CH$PTR(UPLIT(%STRING(%CHAR(12)))),1,TRUE);
STG(%string(' ',fac_name,' annotated listing for element '),FALSE);
OUTTXT(.ELM_PTR,.ELM_LGT,FALSE);
STG(' File ',FALSE);
OUTTXT(.FIL_PTR,.FIL_LGT,FALSE);
STG(' ',FALSE);
DLGT=DATTIM(DBUF);
OUTTXT(CH$PTR(DBUF),.DLGT,FALSE);
!Put out special page number if sequencing is enabled
IF
.SEQ_SEEN
THEN
BEGIN
STG(' Page ',FALSE);
OUTNUM(.PAG_NUM,TRUE)
END
ELSE
OUTTXT(0,0,TRUE);
!Put out 2 blank lines
INCR I FROM 1 TO 2 DO OUTTXT(0,0,TRUE);
END; !End of HDR
GLOBAL ROUTINE OUTTXT (PTR,LEN,TERM) : NOVALUE =
!++
! FUNCTIONAL DESCRIPTION:
!
! Output a line of text (open the output file if not already open)
!
! FORMAL PARAMETERS:
!
! PTR - pointer to line
! LEN - length of line
! TERM - type of termination
!
! IMPLICIT INPUTS:
!
! NONE.
!
! IMPLICIT OUTPUTS:
!
! NONE.
!
! ROUTINE VALUE:
! COMPLETION CODES:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
BEGIN
!Make sure output file is open
IF
.CMD NEQ K_ANNOTATE_COM AND
NOT .O_OPN
THEN
SETOUT();
OUTSTG(.PTR,.LEN,.TERM)
END; !End of OUTTXT
ROUTINE SETINP : NOVALUE =
!++
! FUNCTIONAL DESCRIPTION:
!
! Open the files and do any required initialization.
!
! FORMAL PARAMETERS:
!
!
! IMPLICIT INPUTS:
!
! FIL_LEN - length of file name
! FIL_PTR - pointer to file name
!
! IMPLICIT OUTPUTS:
!
! NONE.
!
! ROUTINE VALUE:
! COMPLETION CODES:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
BEGIN
LOCAL
FIL: VECTOR[CH$ALLOCATION(EXTENDED_FILE_SPEC)],
FIL_P,
FIL_SIZ,
STS;
I_OPN=FALSE;
FIL_P=CH$PTR(FIL);
FIL_P=CH$MOVE(%CHARCOUNT(LIB),CH$PTR(UPLIT(LIB)),.FIL_P);
FIL_P=CH$MOVE(.FIL_LEN,.FIL_PTR,.FIL_P);
FIL_SIZ=CH$DIFF(.FIL_P,CH$PTR(FIL));
STS=$STEP_OPEN(IOB=INPUT_IOB,FILE_SPEC=(.FIL_SIZ,CH$PTR(FIL)),
OPTIONS=INPUT,FAILURE=0);
IF
NOT .STS
THEN
BADXPO(.STS,CAT(('Cannot open master file '),(.FIL_SIZ,CH$PTR(FIL))));
I_OPN=TRUE
END; !End of SETINP
ROUTINE SETOUT : NOVALUE =
!++
! FUNCTIONAL DESCRIPTION:
!
! Open the files and do any required initialization.
!
! FORMAL PARAMETERS:
!
! NONE.
!
! IMPLICIT INPUTS:
!
! FIL_LEN - length of file name
! FIL_PTR - pointer to file name
!
! IMPLICIT OUTPUTS:
!
! NONE.
!
! ROUTINE VALUE:
! COMPLETION CODES:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
BEGIN
LOCAL
FIL: VECTOR[CH$ALLOCATION(EXTENDED_FILE_SPEC)],
FIL_P,
FIL_SIZ,
STS;
IF
.CMD NEQ K_ANNOTATE_COM
THEN
BEGIN
IF
.MERGE EQL NO_MRG
THEN
BEGIN
FIL_P=.FIL_PTR;
FIL_SIZ=.FIL_LEN
END
ELSE
IF
.MERGE EQL MRG_MAIN
THEN
BEGIN
FIL_P=CH$PTR(UPLIT(TM1));
FIL_SIZ=%CHARCOUNT(TM1)
END
ELSE
IF
.MERGE EQL MRG_BRNCH
THEN
BEGIN
FIL_P=CH$PTR(UPLIT(TM2));
FIL_SIZ=%CHARCOUNT(TM2)
END
ELSE
BUG(LIT('Illegal merge designator (RESFIL)'));
IF
.SEQ_SEEN
THEN
STS=$STEP_OPEN(IOB=OUTPUT_IOB,FILE_SPEC=(.FIL_SIZ,.FIL_P),
OPTIONS=OUTPUT,ATTRIBUTES=SEQUENCED,FAILURE=0)
ELSE
STS=$STEP_OPEN(IOB=OUTPUT_IOB,FILE_SPEC=(.FIL_SIZ,.FIL_P),
OPTIONS=OUTPUT,FAILURE=0);
IF
NOT .STS
THEN
BEGIN
ERSXPO(s_onoopen,.STS,CAT(('Cannot open output file '),
(.FIL_SIZ,.FIL_P)));
BYE(s_useverrec,LIT(%string(' Use ',fac_name,' VERIFY/RECOVER')))
END;
O_OPN=TRUE
END
END; !End of SETOUT
ROUTINE TERMINATE : NOVALUE =
!++
! FUNCTIONAL DESCRIPTION:
!
! Close the working files
!
! FORMAL PARAMETERS:
!
! NONE.
!
! IMPLICIT INPUTS:
!
! Input and output IOBs
!
! IMPLICIT OUTPUTS:
!
! NONE.
!
! ROUTINE VALUE:
! COMPLETION CODES:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
BEGIN
IF
.I_OPN
THEN
$step_close(IOB=INPUT_IOB);
!The following conditionals are merely trying to close the output iob
!only if a chronology is not wanted and this isn't a merge
IF
.CHRONO AND
.CHRLEN NEQ 0 AND
.MERGE EQL NO_MRG
THEN
RETURN ;
IF
.O_OPN
THEN
BEGIN
IF
VERNUM( OUTPUT_IOB[IOB$T_RESULTANT] ) GTR 1
THEN
BEGIN
LOCAL
FIL_SPEC : DESC_BLOCK ,
RES_SPEC : DESC_BLOCK ;
$STR_DESC_INIT( DESCRIPTOR = FIL_SPEC,
STRING = (.FIL_LEN, .FIL_PTR)) ;
$STR_DESC_INIT( DESCRIPTOR = RES_SPEC,
STRING = (.OUTPUT_IOB[IOB$H_RESULTANT],.OUTPUT_IOB[IOB$A_RESULTANT]));
IF NATEQL ( FIL_SPEC, RES_SPEC)
THEN
BEGIN
FETSTS = s_isthere;
sysmsg(s_isthere,CAT((.FIL_LEN, .FIL_PTR),
%string(' already exists, so the next ',
%if VaxVms %then 'version', %fi
%if Tops20 %then 'file generation', %fi
' has been created')),0) ;
END ;
END;
$step_close(IOB = OUTPUT_IOB) ;
END ;
END; !End of TERMINATE
GLOBAL ROUTINE WRT_LINE (LENGTH,POINTER) : NOVALUE =
!++
! FUNCTIONAL DESCRIPTION:
!
! Write a text line, including any source audit if existing
!
! FORMAL PARAMETERS:
!
! LENGTH - length of text line
! POINTER - pointer to text line
!
! IMPLICIT INPUTS:
!
! Input and output IOBs
!
! IMPLICIT OUTPUTS:
!
! NONE.
!
! ROUTINE VALUE:
! COMPLETION CODES:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
BEGIN
!See if any pattern exists
IF
NOT .NOTES OR
.NOTLEN EQL 0
THEN
!If no pattern, do it the simple way
BEGIN
OUTTXT(.POINTER,.LENGTH,TRUE);
RETURN
END;
! Don't place an audit mark on a line with just a form-feed
if .length eql 1 and
ch$rchar(.pointer) eql %o'14'
then
begin
outtxt(.pointer, .length, true);
return
end;
!Process left margin audit, if any
IF
.PATPOS EQL 0
THEN
BEGIN
IF
.LGEN_L EQL 0
THEN
!No generation expression, use fill only
BEGIN
LOCAL
FILL_CNT;
FILL_CNT=.PAT_FIL;
UNTIL
.FILL_CNT LEQ 0
DO
BEGIN
STG(' ',FALSE);
FILL_CNT=.FILL_CNT-8
END
END
ELSE
!Place the audit mark in the line
BEGIN
!Left part
IF
.PAT_LLS NEQ 0
THEN
OUTTXT(CH$PTR(PAT_LS),.PAT_LLS,FALSE);
IF
.PAT_GEN
THEN
BEGIN
!Blank fill
INCR I FROM 1 TO .PAT_FIL-.PAT_LLS-.PAT_LRS-.LGEN_L-1 DO
STG(' ',FALSE);
!Output generation number proper
OUTTXT(.LGEN,.LGEN_L,FALSE);
!Right part
IF
.PAT_LRS NEQ 0
THEN
OUTTXT(CH$PTR(PAT_RS),.PAT_LRS,FALSE);
STG(' ',FALSE)
END
ELSE
INCR I FROM 1 TO .PAT_FIL-.PAT_LLS DO
STG(' ',FALSE)
END
END;
!Output the line of text proper
OUTTXT(.POINTER,.LENGTH,FALSE);
!See if a trailing audit is required
IF
.PATPOS NEQ 0 AND
.LGEN_L NEQ 0
THEN
BEGIN
LOCAL
COL_POS;
COL_POS=0;
!Count the effective length of the line
INCR I FROM 1 TO .LENGTH DO
BEGIN
LOCAL
CHAR;
CHAR=CH$RCHAR(CH$PLUS(.POINTER,.I-1));
!Ignore non-printing characters
IF
.CHAR GEQ %C' ' OR
.CHAR EQL %C' '
THEN
BEGIN
IF
.CHAR NEQ %C' '
THEN
COL_POS=.COL_POS+1
ELSE
COL_POS=.COL_POS-(.COL_POS MOD 8)+8
END;
END;
IF
.COL_POS LSS .PATPOS - 1
THEN
!Insert filler
BEGIN
!Fill to nearest tab
IF
.COL_POS+8-(.COL_POS MOD 8) LEQ .PATPOS-1
THEN
BEGIN
STG(' ',FALSE);
COL_POS=.COL_POS+8-(.COL_POS MOD 8)
END;
!Tab as close to end as possible
UNTIL
.COL_POS+8 GTR .PATPOS-2
DO
BEGIN
STG(' ',FALSE);
COL_POS=.COL_POS+8
END;
!Fill in the remainder
INCR I FROM .COL_POS+1 TO .PATPOS-1 DO
STG(' ',FALSE);
END
ELSE
! Special Case . If the line ends exactly where the position is
! we must force a blank
if
.col_pos eql .patpos - 1
then
stg(' ',false)
else
!Line is very long, insert exactly one blank
STG(' ',FALSE);
!Left part
IF
.PAT_LLS NEQ 0
THEN
OUTTXT(CH$PTR(PAT_LS),.PAT_LLS,FALSE);
!Generation number
IF
.PAT_GEN
THEN
BEGIN
OUTTXT(.LGEN,.LGEN_L,FALSE);
!Blank fill
INCR I FROM 1 TO .MAX_G_LGT-.LGEN_L DO
STG(' ',FALSE);
END;
IF
.PAT_LRS NEQ 0
THEN
!Right part
OUTTXT(CH$PTR(PAT_RS),.PAT_LRS,FALSE);
END;
!Not required, terminate the line
OUTTXT(0,0,TRUE)
END; !End of WRT_LINE
END !End of Module RESFIL
ELUDOM