Google
 

Trailing-Edge - PDP-10 Archives - BB-R775E-BM - sources/edt/chmparse.bli
There are 11 other files named chmparse.bli in the archive. Click here to see a list.
 %TITLE 'CHMPARSE - change mode parse and execute'
MODULE CHMPARSE (				! Change mode parse and execute
		IDENT = '3-003'			! File: CHMPARSE.BLI Edit: GB3003
		) =
BEGIN
!
!			  COPYRIGHT (c) 1981, 1985 BY
!	      DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
!		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 WHICH IS NOT SUPPLIED BY DIGITAL.
!

!++
! FACILITY:	EDT -- The DEC Standard Editor
!
! ABSTRACT:
!
!	This module parses and executes a change mode command string.
!
! ENVIRONMENT:	Runs at any access mode - AST reentrant
!
! AUTHOR: Bob Kushlis, CREATION DATE: Unknown
!
! MODIFIED BY:
!
! 1-001	- Original.  DJS 04-Feb-1981.  This module was created by
!	extracting the routine EDT$$CHM_PAREXE  from module CHANGE.BLI.
! 1-002	- Regularize headers.  JBS 03-Mar-1981
! 1-003	- Use new message codes.  JBS 04-Aug-1981
! 1-004 - Add the bell verb. STS 11-Aug-1981
! 1-005 - Add the date verb. STS 31-Aug-1981
! 1-006 - Add the setting of default verb. STS 21-Sep-1981
! 1-007 - Add desel and tgsel. STS 23-Sep-1981
! 1-008 - Add ssel verb. STS 24-Sep-1981
! 1-009	- Add a return value for journal file ended.  JBS 02-Oct-1981
! 1-010 - Revise direction setting for tadj. SMB 22-Oct-1981
! 1-011	- Give an error message on an invalid repeat count.  JBS 10-Mar-1982
! 1-012	- Add NOOVERLAY symbol.  JBS 04-Apr-1982
! 1-013	- Set a flag if control C actually aborts something.  JBS 24-May-1982
! 1-014	- Change alphabetic test.  JBS 19-Jul-1982
! 1-015 - Add the xlate verb. STS 13-Aug-1982
! 1-016 - Add the CLSS verb. STS 26-Aug-1982
! 1-017 - Change to using an alphabetically ordered table. STS 21-Sep-1982
! 1-018	- Move the table into the keyword routine, to reduce the program size
!	   on the PDP-11.  JBS 29-Sep-1982
! 1-019	- Allow lower case commands.  JBS 01-Oct-1982
! 1-020 - Check the length of the command. STS 08-Oct-1982
! 1-021	- Add conditional for VT220 support.  JBS 11-Feb-1983
! 1-022	- Add conditional for WPS support.  JBS 13-Feb-1983
! 1-023	- Correct a typo.  JBS 22-Feb-1983
! 3-001 - Don't need overlay code. CJG 17-Apr-1983
! 3-002 - Add updates from V3 sources.  GB 27-Apr-1983
! 3-003 - Remove VT220 conditional to speed up code. CJG 25-Nov-1983
!--

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

REQUIRE 'EDTSRC:TRAROUNAM';

FORWARD ROUTINE
    EDT$$CHM_PAREXE;				! Parse and execute a change mode command string

!
! INCLUDE FILES:
!

REQUIRE 'EDTSRC:EDTREQ';

LIBRARY 'EDTSRC:TRANSLATE';

!
! MACROS:
!
!	NONE
!
! EQUATED SYMBOLS:
!
!	NONE
!
! OWN STORAGE:
!
!	NONE
!
! EXTERNAL REFERENCES:
!
!	In the routine
%SBTTL 'EDT$$CHM_PAREXE  - change mode parse and execute'

GLOBAL ROUTINE EDT$$CHM_PAREXE (		! Change mode parse and execute
    EXECUTE					! 1 = execute
    ) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	This routine parses and executes a change mode command string.
!
! FORMAL PARAMETERS:
!
!	EXECUTE - 1 if we should execute the command, 0 to parse only.
!
! IMPLICIT INPUTS:
!
!	DIR_MOD
!	CMD_END
!	EXI
!	CMD_PTR
!
! IMPLICIT OUTPUTS:
!
!	DIRN
!	ALT_BUF
!	TADJ
!	CC_DONE
!
! RETURNED VALUE:
!
!	0 - Command failed or control C
!	1 - Command succeeded
!	2 - Journal file ended
!
! SIDE EFFECTS:
!
!	Many
!
!--

    BEGIN

    EXTERNAL ROUTINE
	EDT$$EXE_CHMCMD2,			! Execute the verbs which take an entity specification
	EDT$$EXE_CHMCMD1,		! Execute the verbs which do not take an entity specification
	EDT$$MSG_BELL : NOVALUE,		! Output a message to the terminal with a warning bell
	EDT$$CHK_CC,				! Check to see if a CTRL/C has been typed
	EDT$$GET_BUF : NOVALUE,		! Look for a buffer spec for the cut, paste, and append commands
	EDT$$CHK_CNT,				! Look for a repeat/entity count
	EDT$$CHK_DIR,				! Determine the current direction
	EDT$$SCAN_SEASTR : NOVALUE,		! Scan over the search string when used as an entity
	EDT$$FND_SUBSTR : NOVALUE,	! Isolate the search and replace strings for the SUBSTITUTE command
	EDT$$SCAN_INSSTR : NOVALUE,		! Scan over the string of characters to be inserted
	EDT$$KEY_WORD,				! Compare the command buffer contents to a table of keywords
	EDT$$PARENT,				! Collect and execute a parenthesized string of commands
	EDT$$CNV_UPC;				! Convert string to upper case

    EXTERNAL
	SEA_LEN,				! length of string
	DIRN,					! The current direction.
	DIR_MOD,				! The directional mode.
	CMD_END,				! End of command pointer
	EXI,					! Change mode has been exited.
	CMD_PTR,				! Command string pointer
	ALT_BUF : REF TBCB_BLOCK,		! Alternate buffer used for cut/paste.
	TADJ,					! Count for tabs adjust.
	DFLT_VERB,				! Default verb
	CHAR_INFO : BLOCKVECTOR [256, 1],	! Information about characters
	CC_DONE;				! Set to 1 if control C actually aborted something

    MESSAGES ((INVENT, INVSUBCOM, NUMVALILL));

    LOCAL
	C,
	REPT_COUNT,
	EXPLICIT_REPEAT,
	VERB,
	ENTITY,
	ENTITY_COUNT,
	EXPLICIT_ENTITY_COUNT,
	OPERAND,
	DIR_SAME,
	TADJ_DIR,
	SUCCEED;

!+
! Loop until we hit the end of the command buffer or a closing parenthesis.
!-

    WHILE CH$PTR_GTR (.CMD_END, .CMD_PTR) DO
	BEGIN

	IF EDT$$CHK_CC ()
	THEN
	    BEGIN
	    CC_DONE = 1;
	    RETURN (0);
	    END;

!+
! Skip blanks at beginning of command.
!-

	WHILE (CH$RCHAR (.CMD_PTR) EQL %C' ') DO
	    CMD_PTR = CH$PLUS (.CMD_PTR, 1);

!+
! Look for closing paren.
!-

	IF (CH$RCHAR (.CMD_PTR) EQL %C')') THEN EXITLOOP;

!+
! Set default direction, zero the alternate buffer and zero the
! direction change indicator.
!-
	DIRN = .DIR_MOD;
	ALT_BUF = 0;
!+
! Check for explicit direction specified.
!-
	DIR_SAME = EDT$$CHK_DIR ();
!+
! Look for a count, and remember whether one was seen.
! Give an error message and bail out if the count is invalid.
! (An invalid count means a count greater than 32767.)
!-
	REPT_COUNT = 0;
	EXPLICIT_REPEAT = EDT$$CHK_CNT (REPT_COUNT);

	IF (.EXPLICIT_REPEAT EQL 2)
	THEN
	    BEGIN
	    EDT$$MSG_BELL (EDT$_NUMVALILL);
	    RETURN (0);
	    END;

!+
! Look for the loop.
!-

	IF (CH$RCHAR (.CMD_PTR) EQL %C'(')
	THEN
	    BEGIN

	    IF ((.REPT_COUNT EQL 0) AND (.EXPLICIT_REPEAT EQL 0)) THEN REPT_COUNT = 1;

	    SUCCEED = EDT$$PARENT (.REPT_COUNT, .EXECUTE);

	    IF (.SUCCEED NEQ 1) THEN RETURN (.SUCCEED);

	    END
	ELSE
	    BEGIN
!+
! And now, find the verb of the command.
!-
	    EDT$$KEY_WORD (1, VERB);

	    IF (.VERB EQL 0) THEN VERB = .DFLT_VERB;

!+
! If the command is tabs adjust, then the [+|-] preceding the repeat count is
! used to determine adjustment of the entities right or left.  The global
! direction (ADV or BACK) is not affected by this tab adjust direction.
!-

	    IF (.VERB EQL VERB_K_TADJ)
	    THEN
		BEGIN
		TADJ_DIR = 1;
!+
! If the adjustment direction has explicitly been set by '-', then tab
! adjust to the left.
!-

		IF ((.DIRN EQL DIR_BACKWARD) AND (.DIR_SAME EQL 0)) THEN TADJ_DIR = -1;

		DIRN = .DIR_MOD;
		END;

!+
! This hack prevents the entities SEN and SR from being assumed
! to be a SUBSTITUTE command.
!-

	    IF (.VERB EQL VERB_K_SUBS)
	    THEN

		BEGIN
		C = CH$RCHAR (.CMD_PTR);

		IF .CHAR_INFO [.C, CI_LET]
		THEN
		    BEGIN
		    VERB = .DFLT_VERB;
		    CMD_PTR = CH$PLUS (.CMD_PTR, -1);
		    END;
		END;

!+
! Check to see if it is truly a verb which uses an entity specification.
!-

	    IF (.VERB LSS VERB_K_SEL)
	    THEN
		BEGIN
!+
! And once again, look for the explicit direction.
!-
		DIR_SAME = EDT$$CHK_DIR ();
!+
! Set the entity count to the default of 1, then see if there
! was a count specified.
!-
		ENTITY_COUNT = 1;
		EXPLICIT_ENTITY_COUNT = EDT$$CHK_CNT (ENTITY_COUNT);

		IF (.EXPLICIT_ENTITY_COUNT EQL 2)
		THEN
		    BEGIN
		    EDT$$MSG_BELL (EDT$_NUMVALILL);
		    RETURN (0);
		    END;

!+
! And try for a direction once again.
!-
		DIR_SAME = EDT$$CHK_DIR ();
!+
! Now get the entity.
!-
		IF CH$PTR_GTR (.CMD_END, .CMD_PTR)
		THEN

		    BEGIN
		    C = CH$RCHAR (.CMD_PTR);
		    IF ((.C EQL %C'"') OR (.C EQL %C'''') OR (.C EQL 0))
		    THEN
			BEGIN
			ENTITY = ENT_K_QUOTE;
			CMD_PTR = CH$PLUS (.CMD_PTR, 1);
			END
		    ELSE
			EDT$$KEY_WORD (2, ENTITY);
		    END

		ELSE
		    ENTITY = 0;
!+
! If entity was not found, something is wrong.
!-

		IF (.ENTITY EQL 0)
		THEN
!+
! If verb was defaulted to move, assume it was wrong, otherwise
! it must be the entity which is wrong.
!-
		    BEGIN

		    IF (.VERB NEQ 0) THEN EDT$$MSG_BELL (EDT$_INVENT) ELSE EDT$$MSG_BELL (EDT$_INVSUBCOM);

		    RETURN (0);
		    END;

!+
! If the command is tabs adjust, then process it specially.
! The repeat count and (+ or -) directional indicator are  used
! to determine the adjustment and the entity count and direction
! to select the text.
!-

		IF (.VERB EQL VERB_K_TADJ)
		THEN
		    BEGIN

		    IF (.EXPLICIT_REPEAT EQL 0) THEN REPT_COUNT = 1;

!+
! TADJ_DIR =  1 to adjust right
!          = -1 to adjust left
!-
		    TADJ = .REPT_COUNT * .TADJ_DIR;
		    EXPLICIT_REPEAT = 0;
		    END;

!+
! If there was a repeat count as well as an entity count, multiply
! them out to get the actual number of entities, and only execute
! the command once.
!-

		IF .EXPLICIT_REPEAT THEN ENTITY_COUNT = .REPT_COUNT*.ENTITY_COUNT;

		REPT_COUNT = 1;
!+
! If entity is quoted, get the string.
!-

		IF (.ENTITY EQL ENT_K_QUOTE) THEN EDT$$SCAN_SEASTR ();

!+
! Get the buffer spec if command is cut or append.
!-

		IF (.VERB GEQ VERB_K_CUT) THEN EDT$$GET_BUF ();

!+
! And execute it.
!-

		IF .EXECUTE
		THEN
		    BEGIN
		    SUCCEED = EDT$$EXE_CHMCMD2 (.ENTITY, .ENTITY_COUNT, .VERB);

		    IF (.SUCCEED NEQ 1) THEN RETURN (.SUCCEED);

		    END;

		END
	    ELSE
		BEGIN
!+
! Handle the parsing of the 'funny' verbs, i.e. those which have
! variable length strings as a part.
!-
		OPERAND = .CMD_PTR;

		CASE .VERB FROM VERB_K_SUBS TO VERB_K_CC OF
		    SET

		    [VERB_K_INSERT] :
			EDT$$SCAN_INSSTR ();

		    [VERB_K_XLATE] :

			IF CH$PTR_NEQ (.CMD_PTR, .CMD_END)
			THEN
			    EDT$$SCAN_INSSTR ()
			ELSE
			    SEA_LEN = 0;

		    [VERB_K_SUBS] :
			EDT$$FND_SUBSTR ();

		    [VERB_K_CC] :
			BEGIN
			EDT$$CNV_UPC (.CMD_PTR, 1);
			CMD_PTR = CH$PLUS (.CMD_PTR, 1);
			END;

		    [VERB_K_PASTE] :
			EDT$$GET_BUF ();

		    [OUTRANGE] :
			0;
		    TES;

!+
! Now, execute the command, and terminate the loop if it fails.
!-

		IF .EXECUTE
		THEN
		    BEGIN
		    SUCCEED = EDT$$EXE_CHMCMD1 (.VERB, .REPT_COUNT, .OPERAND, .EXPLICIT_REPEAT);

		    IF (.SUCCEED NEQ 1) THEN RETURN (.SUCCEED);

		    END;

		END;

	    END;

	IF .EXI THEN RETURN (1);

	END;

    RETURN (1);
    END;					! of routine EDT$$CHM_PAREXE


END
ELUDOM