Google
 

Trailing-Edge - PDP-10 Archives - tops20-v7-ft-dist1-clock - 7-sources/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) 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:
!
!	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