Google
 

Trailing-Edge - PDP-10 Archives - bb-h138f-bm - 7-sources/wfinslin.bli
There are 10 other files named wfinslin.bli in the archive. Click here to see a list.
 %TITLE 'WFINSLIN - insert a new line'
MODULE WFINSLIN (				! Insert a new line
		IDENT = '3-003'			! File: WFINSLIN.BLI Edit: CJG3003
		) =
BEGIN
!COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1981, 1988.  ALL RIGHTS RESERVED.
!
!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 THAT IS NOT SUPPLIED BY DIGITAL.
!
!
!++
! FACILITY:	EDT -- The DEC Standard Editor
!
! ABSTRACT:
!
!	Insert a new line into the current text buffer.
!
! ENVIRONMENT:	Runs at any access mode - AST reentrant
!
! AUTHOR: Bob Kushlis, CREATION DATE: October 16, 1978
!
! MODIFIED BY:
!
! 1-001	- Original.  DJS 23-Feb-1981.  This module was created by
!	extracting routine EDT$$INS_LN  from module EDTWF.
! 1-002	- Regularize headers.  JBS 17-Mar-1981
! 1-003 - Change index for line numbers from 10 to 15.  SMB 18-Jan-1982
! 1-004 - Add line number error checks and return value.  SMB 3-Feb-1982
! 1-005	- Handle error return from splitting a bucket.  JBS 09-Jun-1982
! 1-006	- New screen update logic.  JBS 13-Sep-1982
! 1-007	- Remove EDT$$SET_WKLN.  JBS 14-Sep-1982
! 1-008 - Change the call to insert lines.  SMB 21-Sep-1982
! 1-009 - Modify to use new 48 bit macros. STS 01-Oct-1982
! 1-010 - Modify to use new compare macro. 20-Oct-1982
! 1-011	- Count inserted lines, and stop maintaining the screen data
!	   base if we have too many.  JBS 21-Oct-1982
! 1-012	- The counter also counts deleted lines.  JBS 27-Oct-1982
! 1-013 - Add parameters to SC_INSLN.  SMB 02-Dec-1982
! 1-014	- Improve code, add consistency checking.  JBS 28-Dec-1982
! 1-015 - Up the number of recs that can be inserted before SCR_REBUILD is set.  SMB 16-Feb-1983
! 1-016	- Be more defensive with select position updating.  JBS 28-Feb-1983
!
! 3-001 - Rewrite routine for Tops 10/20 to use word addressing.  GB 17-Feb-193
! 3-002 - Zero out text area before inserting new text to fix problem with
!          with bit 35 getting set when using 7 bit bytes.  GB  24-Jun-1983
! 3-003 - Modify ASSERT macro to include error code. CJG 30-Jan-1984
!--

%SBTTL 'Declarations'
!
! TABLE OF CONTENTS:
!

REQUIRE 'EDTSRC:TRAROUNAM';

FORWARD ROUTINE
    EDT$$INS_LN;

!
! INCLUDE FILES:
!

REQUIRE 'EDTSRC:EDTREQ';

!
! MACROS:
!
!	NONE
!
! EQUATED SYMBOLS:
!
!	NONE
!
! OWN STORAGE:
!
!	NONE
!
! EXTERNAL REFERENCES:
!
!	In the routine
%SBTTL 'EDT$$INS_LN  - insert a new line'

GLOBAL ROUTINE EDT$$INS_LN (			! Insert a new line
    REC_ADDR, 					! Pointer to new line
    REC_LEN					! Length of new line
    ) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	Insert a new line in the text buffer.  If there is enough space in the
!	current bucket, text is moved around to make a hole and the new line is
!	inserted, otherwise, the bucket is split into two parts.
!
! FORMAL PARAMETERS:
!
!  REC_ADDR 		the address of the new line
!
!  REC_LEN 		the length of the new line
!
! IMPLICIT INPUTS:
!
!	CUR_BUF
!	WK_BUK
!	WK_CURBUK
!	WK_INSCNT
!	WK_LN
!	LNO0
!	SEL_LN
!	LN_PTR
!	RECS_INSERTED
!	SCR_LNS
!
! IMPLICIT OUTPUTS:
!
!	CUR_BUF
!	WK_LN
!	WK_BUK
!	WK_MODFD
!	WK_INSCNT
!	SEL_POS
!	RECS_INSERTED
!	SCR_REBUILD
!
! ROUTINE VALUE:
!
!	0 = insertion did not occur , 1 = successful insertion
!
! SIDE EFFECTS:
!
!	NONE
!
!--

    BEGIN

    EXTERNAL ROUTINE
	EDT$$FMT_MSG,
	EDT$$CMP_LNO,
	EDT$$WF_MAKECUR : NOVALUE,
	EDT$$WF_SPLTBUK,
	EDT$$SEL_RNGPOS,
	EDT$$SC_INSLN : NOVALUE;

    EXTERNAL
	MAX_LINES : LN_BLOCK,		! Maximum lines EDT can handle
	CUR_BUF : REF TBCB_BLOCK,	! Current text buffer control block
	WK_BUK : 			! Pointer to current bucket
	    REF BLOCK [WF_BUKT_SIZE] FIELD (WFB_FIELDS),
	WK_CURBUK,			! Number of the current bucket
	WK_INSCNT : LN_BLOCK,		! The count of inserted lines
	WK_LN : REF LIN_BLOCK,		! Pointer to current line
	WK_MODFD,			! Flag indicating bucket was modified
	LNO0 : LNOVECTOR [14],
	SEL_POS,				! Select position
	LN_PTR,				! Pointer into line buffer
	LN_BUF,				! The line buffer
	SEL_LN,				! Select line
	SCR_LNS,			! The number of text lines on the screen
	RECS_INSERTED,	! Number of records inserted and deleted since the last screen update
	SCR_REBUILD;			! 1 = the screen data structures must be rebuilt from the work file

    MESSAGES ((MAXLINVAL, INSMEM));

    LOCAL
	OLD_NEXT,
	INS_LEN;

!+
! Update the line and character counts, but first be sure we aren't exceeding
! the maximum number of lines allowed
!-

    IF (EDT$$CMP_LNO (CUR_BUF [TBCB_LINE_COUNT], MAX_LINES) GEQ 0)
    THEN
	BEGIN
	EDT$$FMT_MSG (EDT$_MAXLINVAL);
	RETURN (0);
	END;

!+
! Fix up select range if necessary.
!-

    CASE EDT$$SEL_RNGPOS () FROM -1 TO 1 OF
	SET

	[0] : 					! Current line is select line

	    IF CH$PTR_GTR (.SEL_POS, .LN_PTR)
	    THEN
		BEGIN
		IF CH$PTR_LSS (CH$PTR (LN_BUF, 0, BYTE_SIZE), CH$PLUS (.SEL_POS, -.REC_LEN))
		THEN
		    SEL_POS = CH$PTR (LN_BUF, 0, BYTE_SIZE)
		ELSE
		    SEL_POS = CH$PLUS (.SEL_POS, -.REC_LEN);

		ADDLINE (LNO0, SEL_LN, SEL_LN);
		END;

	[1] : 					! Current line is before select line
	    ADDLINE (LNO0, SEL_LN, SEL_LN);

	[-1] : 					! Current line is after select line, or no select
	    BEGIN
	    0
	    END;

	[OUTRANGE] :
	    ASSERT (8, 0);
	TES;

!+
! If we are not going to rebuild the screen data base from the work file,
! tell the screen updater that we have inserted a line.
!-

    IF ( NOT .SCR_REBUILD)
    THEN
	BEGIN
	RECS_INSERTED = .RECS_INSERTED + 1;

	IF (.RECS_INSERTED GTR (.SCR_LNS*2))
	THEN
	    SCR_REBUILD = 1
	ELSE
	    EDT$$SC_INSLN (.REC_ADDR, .REC_LEN);

	END;

!+
! Update the various counters for this text buffer.
!-
    ADDLINE (LNO0, CUR_BUF [TBCB_LINE_COUNT], CUR_BUF [TBCB_LINE_COUNT]);
    CUR_BUF [TBCB_CHAR_COUNT] = .CUR_BUF [TBCB_CHAR_COUNT] + .REC_LEN;
    ADDLINE (LNO0, CUR_BUF [TBCB_CUR_LIN], CUR_BUF [TBCB_CUR_LIN]);
    WK_LN = .WK_BUK + .CUR_BUF [TBCB_LINE_ADDR];
!+
! Compute length of line to be inserted (in words), including line no. info.
!-
    INS_LEN = ((.REC_LEN + BYTES_PER_WORD - 1) / BYTES_PER_WORD) + LIN_FIXED_SIZE + 1;
!+
! Will it fit in this bucket?
!-

    IF ((.WK_BUK [WFB_END] + .INS_LEN) GTRU WF_BUKT_SIZE)
    THEN
!+
! If we are at the beginning of a bucket and it is not the
! first bucket, then check out the previous bucket.
!-

	IF ((.CUR_BUF [TBCB_LINE_ADDR] EQL WFB_FIXED_SIZE) AND 	!
	    (.WK_BUK [WFB_PREV_BUKT] NEQ 0))
	THEN
	    BEGIN
!+
! Read the previous bucket and position to it's end.
!-
	    EDT$$WF_MAKECUR (.WK_BUK [WFB_PREV_BUKT]);
	    CUR_BUF [TBCB_LINE_ADDR] = .WK_BUK [WFB_END];
	    CUR_BUF [TBCB_CUR_BUKT] = .WK_CURBUK;
	    END;

!+
! If it still doesn't fit, then split the bucket.  Note that
! the while loop is here because it may not fit after the first
! split.  In this case the second split is guaranteed to create
! a new bucket and the line must fit.
!-

    WHILE ((.WK_BUK [WFB_END] + .INS_LEN) GTRU WF_BUKT_SIZE) DO
	BEGIN

	IF ( NOT EDT$$WF_SPLTBUK ())
	THEN
	    BEGIN
	    EDT$$FMT_MSG (EDT$_INSMEM);
	    RETURN (0);
	    END;

	END;

!+
! Make a hole for the line to be inserted.
!-
    WK_LN = .WK_BUK + .CUR_BUF [TBCB_LINE_ADDR];

    EDT$$CPY_MEM (.WK_BUK [WFB_END] - .CUR_BUF [TBCB_LINE_ADDR], .WK_LN, .WK_LN + .INS_LEN);
!+
! Update the end of bucket field to reflect new size.
!-
    WK_BUK [WFB_END] = .WK_BUK [WFB_END] + .INS_LEN;
!+
! And move the line into the bucket buffer.
!-
    WK_LN [LIN_LENGTH] = .REC_LEN;
    CH$FILL (0, .INS_LEN - (LIN_FIXED_SIZE + 1), CH$PTR (WK_LN [LIN_TEXT], 0, 36));
    CH$MOVE (.REC_LEN, .REC_ADDR, CH$PTR (WK_LN [LIN_TEXT], 0, BYTE_SIZE));
!+
! Put offset to start of this line in next word & setup offset to next line
!-
    .WK_LN + .INS_LEN - 1 = .INS_LEN;
    WK_LN [LIN_NEXT] = .INS_LEN;
!+
! Update the record pointer
!-
    CUR_BUF [TBCB_LINE_ADDR] = .CUR_BUF [TBCB_LINE_ADDR] + .INS_LEN;
!+
! Set the "modified" flag, and bump the count of inserted lines.
!
    WK_MODFD = 1;
    ADDLINE (WK_INSCNT, LNO0, WK_INSCNT);
!+
! Now make sure we are positioned correctly.
!-

    IF (.CUR_BUF [TBCB_LINE_ADDR] GEQ .WK_BUK [WFB_END])
    THEN

	IF (.WK_BUK [WFB_NEXT_BUKT] NEQ 0)
	THEN
	    BEGIN
	    EDT$$WF_MAKECUR (.WK_BUK [WFB_NEXT_BUKT]);
	    CUR_BUF [TBCB_LINE_ADDR] = WFB_FIXED_SIZE;
	    CUR_BUF [TBCB_CUR_BUKT] = .WK_CURBUK;
	    END;

    WK_LN = .WK_BUK + .CUR_BUF [TBCB_LINE_ADDR];
    RETURN (1)
    END;					! of routine EDT$$INS_LN


END
ELUDOM