Google
 

Trailing-Edge - PDP-10 Archives - BB-X117B-SB_1986 - 10,7/tkb36/cmds.bli
There are 2 other files named cmds.bli in the archive. Click here to see a list.
!<REL4A.TKB-VNP>CMDS.BLI.7,  3-Dec-79 14:25:36, Edit by SROBINSON
MODULE CMDS (					! COMMAND SCANNER
		IDENT = 'X2.0'
		) =
BEGIN
!
!
!COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1980,1981,1982,1986. 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: TKB-20
!
! ABSTRACT:
!
!
! THIS IS THE COMMAND SCANNER FOR THE TASK BUILDER.
!
!
! ENVIRONMENT: TOPS-20
!
! AUTHOR: J. SAUTER, CREATION DATE: 14-DEC-77
!
! MODIFIED BY:
!
!	Scott G. Robinson, 15-FEB-79 : VERSION X0.1-2A
!	- Make calls to CMDLIN include the prompt
!-----------------------------------------------------------------------
!
!	Scott G. Robinson, 3-DEC-79 : Version X2.0
!	- Setup for DECnet-10 compatibility
!
!	, : VERSION
! 01	-
!--

!<BLF/PAGE>
!
! TABLE OF CONTENTS:
!

FORWARD ROUTINE
    UPPER_CASE,					!CONVERT LOWER CASE TO UPPER
    SCN_FILE_NAME,				!SCAN A FILE NAME
    SCN_SWITCH,					!SCAN A SWITCH
    CMDLIN,					!PROCESS A COMMAND LINE (GLOBAL)
    GET_SW,					!GET SWITCH AND VALUE (GLOBAL)
    SEL_SWITCH;					! SUBROUTINE USED BY GET_SW

!
! INCLUDE FILES:
!

LIBRARY 'TKBLIB';

!REQUIRE 'BLOCKH.REQ';				!PREPARE TO DEFINE STORAGE BLOCKS
!REQUIRE 'FILE.REQ';				!DEFINE FILE BLOCK
!REQUIRE 'FILSW.REQ';				!DEFINE FILE SWITCH BLOCK
!REQUIRE 'BLOCKT.REQ';				!END OF DEFINING BLOCKS
!
! MACROS:
!
!	NONE
!
! EQUATED SYMBOLS:
!
!	NONE
!
! OWN STORAGE:
!
!	NONE
!
! EXTERNAL REFERENCES:
!

EXTERNAL ROUTINE
    BLD_CHAIN,					!BUILD A MULTIPLE-POINTER LIST
    CLOSE : NOVALUE,				!CLOSE A FILE
    OPEN,					!OPEN A FILE
    ERRMSG : NOVALUE,				!PRINT ERROR MESSAGE
    ERROR,					!ANNOUNCE A PROGRAMMING ERROR
    FND_CHAIN,					!FIND A BLOCK IN A CHAIN
    FREBLK : NOVALUE,				!RETURN A BLOCK TO THE FREE LIST
    GETBLK,					!GET A BLOCK FROM THE FREE LIST
    INPUT,					!READ FROM I/O DEVICE
    PCRLF : NOVALUE,				!PRINT CRLF
    OUTSTR : NOVALUE;				!PRINT A STRING

ROUTINE UPPER_CASE (CHAR) = 			!CONVERT LC TO UC

!++
! FUNCTIONAL DESCRIPTION:
!
!
!
!	ROUTINE TO CONVERT LOWER CASE CHARACTERS TO UPPER CASE
!	ALL CHARACTERS FROM LOWER CASE "A" TO LOWER CASE "Z"
!	GET OCTAL 40 SUBTRACTED FROM THEM.  ALL OTHER CHARACTERS
!	ARE RETURNED UNCHANGED.
!
!
! FORMAL PARAMETERS:
!
!	CHAR - THE CHARACTER TO BE CONVERTED
!
! IMPLICIT INPUTS:
!
!	NONE
!
! IMPLICIT OUTPUTS:
!
!	NONE
!
! ROUTINE VALUE:
!
!	THE CHARACTER, CONVERTED TO UPPER CASE IF NECESSARY
!
! SIDE EFFECTS
!
!	NONE
!
!--

    BEGIN

    SELECTONE .CHAR OF
	SET

	[%C'a' TO %C'z'] :
	    .CHAR - %O'40';

	[OTHERWISE] :
	    .CHAR;
	TES

    END;
ROUTINE SCN_FILE_NAME (PTR) = 			! SCAN FILE NAME

!++
! FUNCTIONAL DESCRIPTION:
!
!	SCAN A FILE NAME.  STOP ON PROPER DELIMETER.
!
! FORMAL PARAMETERS:
!
!	PTR - POINTER TO TEXT; GETS UPDATED.
!
! IMPLICIT INPUTS:
!
!	THE TEXT POINTED TO IS READ
!
! IMPLICIT OUTPUTS:
!
!	NONE
!
! ROUTINE VALUE:
!
!	POINTER TO FILE BLOCK, OR 0 IF OUT OF STORAGE.
!
! SIDE EFFECTS
!
!	OBTAINS STORAGE FROM THE FREE LIST
!
!--

    BEGIN

    LOCAL
	CHAR,
	FILE_PTR : REF FILE_BLOCK,
	FIL_N_CTR,
	FIL_N_PTR,
	SCAN_DONE;

!

    IF ((FILE_PTR = GETBLK (FILE_TYP, FILE_LEN)) EQL 0)
    THEN
	BEGIN
	ERRMSG (0, 1, UPLIT (%ASCIZ'SCAN_FILE_NAME'), 0, 0, 0, 0);
	0
	END
    ELSE
	BEGIN
	FIL_N_PTR = CH$PTR (FILE_PTR [FILE_NAME], -1);
	SCAN_DONE = 0;
	FIL_N_CTR = 0;

	DO
	    BEGIN
	    CHAR = UPPER_CASE (CH$A_RCHAR (.PTR));

	    CASE .CHAR FROM 0 TO 127 OF
		SET

		[%C'A' TO %C'Z', %C'0' TO %C'9', %C'.', %C'<', %C'>', %C'[', %C']', %C':', %C'-'] :
		    BEGIN			!VALID CHAR IN FILE NAME

		    IF (.FIL_N_CTR LSS (LEN_FILE_STRING - 1))
		    THEN
			BEGIN
			CH$A_WCHAR (.CHAR, FIL_N_PTR);
			FIL_N_CTR = .FIL_N_CTR + 1;
			END
		    ELSE
			SCAN_DONE = -1;

		    END;

		[%C',', %C'/', %C'=', 0] :
		    BEGIN			!VALID DELIMETER
		    SCAN_DONE = 1;
		    .PTR = CH$PLUS (..PTR, -1);
		    END;

		[INRANGE] :
		    BEGIN
		    SCAN_DONE = -1;
		    CH$A_WCHAR (.CHAR, FIL_N_PTR);
		    END;
		TES;

	    END
	UNTIL (.SCAN_DONE NEQ 0);

	CH$A_WCHAR (0, FIL_N_PTR);		!TERMINATE FILE NAME

	IF (.SCAN_DONE LSS 0)
	THEN
	    ERRMSG (0, 2, UPLIT (%ASCIZ'SCAN_FILE_NAME'), FILE_PTR [FILE_NAME], 0, 0,
		0);

	.FILE_PTR				!RETURN POINTER TO FILE BLOCK
	END					!GOT STORAGE
    END;					!ROUTINE SCN_FIL_NAME (SCAN_FILE_NAME)

ROUTINE SCN_SWITCH (PTR) = 			! SCAN A SWITCH

!++
! FUNCTIONAL DESCRIPTION:
!
!	SCAN A SWITCH WITH OPTIONAL VALUE
!
! FORMAL PARAMETERS:
!
!	PTR - POINTER TO TEXT; GETS UPDATED.
!	 INITIALLY POINTS RIGHT AFTER THE "/".
!
! IMPLICIT INPUTS:
!
!	THE TEXT POINTED TO IS READ
!
! IMPLICIT OUTPUTS:
!
!	NONE
!
! ROUTINE VALUE:
!
!	POINTER TO LIST OF SWITCH BLOCKS, OR 0 IF OUT OF STORAGE.
!
! SIDE EFFECTS
!
!	OBTAINS STORAGE FROM THE FREE LIST.
!	THE POINTER IS LEFT POINTING TO THE FIRST CHAR AFTER THE SWITCH
!
!--

    BEGIN

    LOCAL
	CHAR,
	DEC_VAL,
	OCT_BAD,
	OCT_VAL,
	SCAN_DONE,
	SW_PTR : REF FILSW_BLOCK,
	VALUE_TEXT : VECTOR [CH$ALLOCATION (LEN_FSW_TEXT)],
	VAL_TYPE,
	WORD_CTR,
	WORD_DONE,
	WORD_PTR;

    SCAN_DONE = 0;

    IF ((SW_PTR = GETBLK (FILSW_TYP, FILSW_LEN)) EQL 0)
    THEN
	BEGIN
	ERRMSG (0, 1, UPLIT (%ASCIZ'SCAN_SWITCHES'), 0, 0, 0, 0);
	SCAN_DONE = -1;
	END;

    IF (.SCAN_DONE EQL 0)
    THEN
	BEGIN					!SETUPS ARE OK
	WORD_DONE = 0;
	WORD_CTR = 0;
	WORD_PTR = CH$PTR (SW_PTR [FSW_NAME], -1);

	WHILE (.WORD_DONE EQL 0) DO
	    BEGIN
	    CHAR = UPPER_CASE (CH$A_RCHAR (.PTR));

	    SELECT .CHAR OF
		SET

		[%C'A' TO %C'Z', %C'0' TO %C'9', %C'.', %C'-'] :
		    BEGIN

		    IF (.WORD_CTR LSS (LEN_FSW_NAME - 1))
		    THEN
			BEGIN
			CH$A_WCHAR (.CHAR, WORD_PTR);
			WORD_CTR = .WORD_CTR + 1;
			END
		    ELSE
			BEGIN
			SCAN_DONE = -1;
			WORD_DONE = -1;
			END;

		    END;

		[%C'/', %C',', %C'=', 0] :
		    BEGIN
		    SCAN_DONE = 1;
		    .PTR = CH$PLUS (..PTR, -1);
		    END;

		[%C':', %C'/', %C',', %C'=', 0] :
		    BEGIN
		    WORD_DONE = 1;
		    END;

		[OTHERWISE] :
		    BEGIN
		    SCAN_DONE = -1;		!INVALID CHARACTER
		    WORD_DONE = -1;
		    END;
		TES;

	    END;				!SCAN OF WORD

	IF (.SCAN_DONE EQL 0)
	THEN
	    BEGIN				!WE HAVE A VALUE FOR THIS SWITCH
	    WORD_DONE = 0;
	    CHAR = CH$A_RCHAR (.PTR);

	    SELECTONE UPPER_CASE (.CHAR) OF
		SET

		[%C'0' TO %C'9'] :
		    BEGIN			!NUMERIC
		    DEC_VAL = 0;
		    OCT_VAL = 0;
		    OCT_BAD = 0;
		    VAL_TYPE = 1;		!ASSUME OCTAL NUMBER

		    WHILE (.WORD_DONE EQL 0) DO
			BEGIN

			SELECT .CHAR OF
			    SET

			    [%C'0' TO %C'7'] :
				OCT_VAL = (.OCT_VAL*8) + (.CHAR - %C'0');

			    [%C'0' TO %C'9'] :
				DEC_VAL = (.DEC_VAL*10) + (.CHAR - %C'0');

			    [%C'8' TO %C'9'] :
				OCT_BAD = 1;

			    [%C'.'] :
				BEGIN
				VAL_TYPE = 2;	!MUST BE DECIMAL NUMBER
				WORD_DONE = 1;
				SCAN_DONE = 1;
				END;

			    [%C'/', %C',', %C'=', 0] :
				BEGIN
				SCAN_DONE = 1;
				WORD_DONE = 1;
				.PTR = CH$PLUS (..PTR, -1);
				END;

			    [OTHERWISE] :
				BEGIN
				SCAN_DONE = -1;
				WORD_DONE = -1;
				END;
			    TES;

			IF (.WORD_DONE EQL 0) THEN CHAR = CH$A_RCHAR (.PTR);

			END;

		    END;			!NUMERIC

		[%C'A' TO %C'Z', %C'$', %C'.'] :
		    BEGIN			!TEXT
		    WORD_CTR = 0;
		    WORD_PTR = CH$PTR (VALUE_TEXT, -1);
		    VAL_TYPE = 3;

		    WHILE (.WORD_DONE EQL 0) DO
			BEGIN

			SELECTONE UPPER_CASE (.CHAR) OF
			    SET

			    [%C'A' TO %C'Z', %C'0' TO %C'9', %C'$', %C'.'] :
				BEGIN

				IF (.WORD_CTR LSS (LEN_FSW_TEXT - 1))
				THEN
				    BEGIN
				    CH$A_WCHAR (.CHAR, WORD_PTR);
				    WORD_CTR = .WORD_CTR + 1;
				    END
				ELSE
				    BEGIN
				    SCAN_DONE = -1;
				    WORD_DONE = -1;
				    END;

				END;

			    [%C'/', %C',', %C'=', 0] :
				BEGIN
				SCAN_DONE = 1;
				WORD_DONE = 1;
				.PTR = CH$PLUS (..PTR, -1);
				END;

			    [OTHERWISE] :
				BEGIN
				SCAN_DONE = -1;
				WORD_DONE = -1;
				END;
			    TES;

			IF (.WORD_DONE EQL 0) THEN CHAR = CH$A_RCHAR (.PTR);

			END;

		    END;			!TEXT

		[OTHERWISE] :
		    BEGIN
		    SCAN_DONE = -1;
		    WORD_DONE = -1;
		    END;
		TES;

!

	    IF (.WORD_DONE GTR 0)
	    THEN
		BEGIN

		CASE .VAL_TYPE FROM 1 TO 3 OF
		    SET

		    [1] :
			BEGIN			!OCTAL NUMBER

			IF (.OCT_BAD NEQ 0)
			THEN
			    SCAN_DONE = -1
			ELSE
			    BEGIN
			    SW_PTR [FSW_VAL] = .OCT_VAL;
			    SW_PTR [FSW_VAL_PRES] = 1;
			    END;

			END;

		    [2] :
			BEGIN			!DECIMAL NUMBER
			SW_PTR [FSW_VAL] = .DEC_VAL;
			SW_PTR [FSW_VAL_PRES] = 1;
			END;

		    [3] :
			BEGIN			!TEXT
			CH$MOVE (.WORD_CTR, CH$PTR (VALUE_TEXT), CH$PTR (SW_PTR [FSW_TEXT]));
			SW_PTR [FSW_TEXT_PRES] = 1;
			END;
		    TES;

		END;				!WORD_CTR GTR 0

	    END					!VALUE FOR THIS SWITCH
	END;					!SETUPS ARE OK

    IF (.SCAN_DONE LEQ 0)
    THEN
	BEGIN

	IF (.SW_PTR NEQ 0) THEN FREBLK (.SW_PTR);

	0
	END
    ELSE
	BEGIN
	.SW_PTR
	END

    END;					!ROUTINE SCN_SWITCH (SCAN_SWITCHES)

GLOBAL ROUTINE CMDLIN (CHANNEL, UP_FILE, PROMPT) = 	! SCAN A COMMAND LINE

!++
! FUNCTIONAL DESCRIPTION:
!
!	ROUTINE TO PROCESS A COMMAND LINE
!	HANDLES INDIRECTION AND SWITCHES
!
! FORMAL PARAMETERS:
!
!	CHANNEL - FIRST CHANNEL OVER WHICH TO GET INPUT
!	UP_FILE - POINTER TO PREVIOUS FILE BLOCK (ROOT IF CHANNEL = 0)
!	PROMPT - POINTER TO PROMPT STRING (ISSUED TO TERMINAL)
!
! IMPLICIT INPUTS:
!
!	DATA FROM THE INDICATED CHANNEL, AND FROM SPECIFIED FILES
!
! IMPLICIT OUTPUTS:
!
!	ADDS FILES TO THE DATA STRUCTURE POINTED TO BY UP_FILE
!
! ROUTINE VALUE:
!
!	0 = SYNTAX ERROR, 1 = SUCCESS.
!
! SIDE EFFECTS
!
!	GETS STORAGE FROM FREE LIST
!	READS FROM SPECIFIED I/O CHANNEL, AND FROM
!	 FILES AS SPECIFIED IN THE COMMAND STRING
!
!--

    BEGIN

    BIND
	ROUTINE_NAME = UPLIT (%ASCIZ'CMDLIN');

    LOCAL
	CHAN,
	CHAR,
	FILE_PTR : REF FILE_BLOCK,
	FIRST_FILE : REF FILE_BLOCK,
	HIGHER_FILE : REF FILE_BLOCK,
	IND_FILE_PTR : VECTOR [5],		!POINTS TO FILE BLOCKS
	NXT_FILE_PTR : REF FILE_BLOCK,
	SCAN_DONE,
	SEEN_DELIM,
	SEEN_CONT,
	SEEN_EQUAL,
	SWITCH_PTR : REF FILSW_BLOCK,
	TEXT_CTR,
	TEXT_LINE : VECTOR [CH$ALLOCATION (200)],
	TEXT_PTR,
	TMP_FILE_PTR : REF FILE_BLOCK;

    FIRST_FILE = 0;
    SEEN_EQUAL = 0;				!NO '=' YET
    SEEN_CONT = -1;				!PRETEND WE HAVE SEEN CONT MARK
    FILE_PTR = 0;				!NO FILES SEEN YET
    CHAN = .CHANNEL;				!START ON SPECIFIED CHANNEL
    HIGHER_FILE = .UP_FILE;			!START WITH SPECIFIED HIGHER FILE
    IND_FILE_PTR [.CHAN] = .UP_FILE;		!REMEMBER FOR INDIRECT FILES
!
! LOOP HERE TO SCAN CONTINUED LINES
!

    WHILE ((.SEEN_CONT NEQ 0) OR (.CHAN NEQ .CHANNEL)) DO
	BEGIN
	SEEN_CONT = 0;
	SEEN_DELIM = -1;

	IF (.CHAN EQL 0)
	THEN
	    BEGIN
	    OUTSTR (.CHAN, .PROMPT);
	    END;

!
! ABSORB TEXT LINE FROM INPUT DEVICE
!
	TEXT_CTR = 0;
	TEXT_PTR = CH$PTR (TEXT_LINE, -1);

	DO
	    BEGIN
	    CHAR = INPUT (.CHAN);

	    IF (.CHAR LSS 0)
	    THEN
		BEGIN

		IF (.CHAN GTR .CHANNEL)
		THEN
		    BEGIN
		    CLOSE (.CHAN);
		    CHAN = .CHAN - 1;
		    HIGHER_FILE = .IND_FILE_PTR [.CHAN];
		    END
		ELSE
		    ERRMSG (0, 9, ROUTINE_NAME, 0, 0, 0, 0);

		END
	    ELSE

		IF ((.CHAR GEQ %C' ') AND (.TEXT_CTR LSS 200)) THEN CH$A_WCHAR (.CHAR, TEXT_PTR);

	    END
	UNTIL ((.CHAR EQL %O'12') OR ((.CHAR LSS 0) AND (.CHAN EQL .CHANNEL)));

	CH$A_WCHAR (0, TEXT_PTR);		!APPEND NULL TO LINE IMAGE
	TEXT_PTR = CH$PTR (TEXT_LINE, -1);

	IF (.CHAR EQL %O'12')
	THEN
	    SCAN_DONE = 0
	ELSE

	    IF ((.CHAR LSS 0) AND (.CHAN EQL .CHANNEL) AND (SEEN_CONT EQL 0))
	    THEN
		SCAN_DONE = 1
	    ELSE
		SCAN_DONE = -1;

!
! NOW SCAN THE LINE
!

	WHILE (.SCAN_DONE EQL 0) DO
	    BEGIN
	    CHAR = UPPER_CASE (CH$A_RCHAR (TEXT_PTR));

	    SELECTONE .CHAR OF
		SET

		[%C'@'] :
		    BEGIN			!INDIRECT FILE

		    IF (.CHAN GEQ 4)
		    THEN
			ERRMSG (0, 8, ROUTINE_NAME, TEXT_LINE, 0, 0, 0)
		    ELSE

			IF ((IND_FILE_PTR [.CHAN + 1] = SCN_FILE_NAME (TEXT_PTR)) EQL 0)
			THEN
			    ERRMSG (0, 2,
				ROUTINE_NAME, TEXT_LINE, 0, 0, 0)
			ELSE
			    BEGIN
			    TMP_FILE_PTR = .IND_FILE_PTR [.CHAN + 1];
			    TMP_FILE_PTR [FILE_FLAG_IND] = 1;

			    IF (OPEN (.CHAN + 1, TMP_FILE_PTR [FILE_NAME], 1, 0, UPLIT (%ASCIZ'CMD')) NEQ 0)
			    THEN
				BEGIN
				HIGHER_FILE [FILE_DOWN] = BLD_CHAIN (.HIGHER_FILE, .HIGHER_FILE [FILE_DOWN],
				    .TMP_FILE_PTR);
				TMP_FILE_PTR [FILE_HIGH] = .HIGHER_FILE;
				HIGHER_FILE = .TMP_FILE_PTR;
				CHAN = .CHAN + 1;
				END;

			    END;

		    END;

		[%C'A' TO %C'Z', %C'0' TO %C'9'] :
		    BEGIN			!ALPHANUMERIC, MUST START A FILE SPEC

		    IF (.SEEN_DELIM EQL 0)
		    THEN
			BEGIN
			ERRMSG (0, 6, ROUTINE_NAME, TEXT_LINE, 0, 0, 0);
			SCAN_DONE = -1;
			END
		    ELSE
			BEGIN
			TEXT_PTR = CH$PLUS (.TEXT_PTR, -1);
			NXT_FILE_PTR = SCN_FILE_NAME (TEXT_PTR);

			IF (.NXT_FILE_PTR EQL 0)
			THEN
			    SCAN_DONE = -1
			ELSE
			    BEGIN
			    NXT_FILE_PTR [FILE_PREV] = .FILE_PTR;
			    NXT_FILE_PTR [FILE_HIGH] = .HIGHER_FILE;
			    HIGHER_FILE [FILE_DOWN] = BLD_CHAIN (.HIGHER_FILE, .HIGHER_FILE [FILE_DOWN],
				.NXT_FILE_PTR);

			    IF (.FILE_PTR NEQ 0) THEN FILE_PTR [FILE_NEXT] = .NXT_FILE_PTR;

			    FILE_PTR = .NXT_FILE_PTR;

			    IF (.FIRST_FILE EQL 0) THEN FIRST_FILE = .FILE_PTR;

			    IF (.SEEN_EQUAL NEQ 0) THEN FILE_PTR [FILE_FLAG_IN] = 1;

			    SEEN_DELIM = 0;
			    END;

			END;

		    END;

		[%C'/'] :
		    BEGIN			!SWITCHES

		    IF (.SEEN_DELIM NEQ 0)
		    THEN
			ERRMSG (0, 7, ROUTINE_NAME, TEXT_LINE, 0, 0, 0)
		    ELSE
			BEGIN
			SWITCH_PTR = SCN_SWITCH (TEXT_PTR);

			IF (.SWITCH_PTR EQL 0)
			THEN
			    ERRMSG (0, 6, ROUTINE_NAME, TEXT_LINE, 0, 0, 0)
			ELSE
			    BEGIN

			    IF ((FILE_PTR [FILE_SWITCHES] = BLD_CHAIN (.FILE_PTR, .FILE_PTR [FILE_SWITCHES],
				    .SWITCH_PTR)) EQL 0)
			    THEN
				ERRMSG (0, 1, ROUTINE_NAME, 0, 0, 0, 0);

			    END;

			END;

		    END;

		[%C','] :
		    BEGIN			!COMMA, SEPARATES FILE SPECS
		    SEEN_DELIM = -1;
		    END;

		[%C'-'] :
		    BEGIN			!DASH, INDICATES CONTINUATION IN RIGHT CONTEXT

		    IF (SEEN_DELIM NEQ 0) THEN SEEN_CONT = -1;

		    SEEN_DELIM = 0;
		    END;

		[%C'='] :
		    BEGIN			!EQUAL SIGN, SEPATATES OUTPUT FROM INPUT FILES

		    IF ((.SEEN_DELIM NEQ 0) OR (.SEEN_EQUAL NEQ 0))
		    THEN
			BEGIN
			ERRMSG (0, 6, ROUTINE_NAME, TEXT_LINE, 0, 0, 0);
			SCAN_DONE = -1;
			END
		    ELSE
			BEGIN
			SEEN_DELIM = -1;
			SEEN_EQUAL = -1;
!
! MARK ALL FILE SPECS ALREADY SEEN AS BEING TO THE LEFT OF
!  THE EQUAL SIGN.
!
			TMP_FILE_PTR = .FIRST_FILE;

			WHILE (.TMP_FILE_PTR NEQ 0) DO
			    BEGIN
			    TMP_FILE_PTR [FILE_FLAG_OUT] = 1;
			    TMP_FILE_PTR = .TMP_FILE_PTR [FILE_NEXT];
			    END;

			END;

		    END;

		[0] :
		    BEGIN			! END OF LINE
		    SCAN_DONE = 1;
		    END;

		[OTHERWISE] :
		    BEGIN
		    ERRMSG (0, 2, ROUTINE_NAME, TEXT_LINE, 0, 0, 0);
		    SCAN_DONE = -1;
		    END;
		TES;

	    END;				! END OF SCAN LOOP

	END;					! END OF CONTINUATION LINES

    WHILE (.CHAN NEQ .CHANNEL) DO
	BEGIN
	CLOSE (.CHAN);
	CHAN = .CHAN - 1;
	END;

    .SCAN_DONE
    END;

!

GLOBAL ROUTINE GET_SW (FILE_PTR, SWITCH_NAME) = 	!GET SWITCH AND VALUE

!++
! FUNCTIONAL DESCRIPTION:
!
!	GET A SWITCH (ON A FILE) AND ITS VALUE
!
! FORMAL PARAMETERS:
!
!	FILE_PTR - THE FILE BLOCK THAT MAY HAVE THE SPECIFIED SWITCH
!	SWITCH_NAME - NAME OF THE SWITCH, SEVEN CHARACTERS, LAST NULL.
!
! IMPLICIT INPUTS:
!
!	NONE
!
! IMPLICIT OUTPUTS:
!
!	NONE
!
! ROUTINE VALUE:
!
!	POINTER TO THE SWITCH BLOCK, OR 0
!
! SIDE EFFECTS
!
!	NONE
!
!--

    BEGIN

    MAP
	FILE_PTR : REF FILE_BLOCK;

    IF (.FILE_PTR EQL 0) THEN 0 ELSE FND_CHAIN (.FILE_PTR [FILE_SWITCHES], SEL_SWITCH, .SWITCH_NAME)

    END;					!OF GET_SW

ROUTINE SEL_SWITCH (FILSW_PTR, SWITCH_NAME) = 	!SEE IF A SWITCH IS ON A FILE

!++
! FUNCTIONAL DESCRIPTION:
!
!	SEE IF A SWITCH IS ON A FILE.  USED IN CALL TO FND_CHAIN.
!
! FORMAL PARAMETERS:
!
!	FILSW_PTR - POINTER TO A FILE SWITCH TO TEST
!	SWITCH_NAME - POINTER TO NAME OF SWITCH TO LOOK FOR
!
! IMPLICIT INPUTS:
!
!	NONE
!
! IMPLICIT OUTPUTS:
!
!	NONE
!
! ROUTINE VALUE:
!
!	0 IF THIS IS NOT THE PROPER SWITCH (WHICH WILL CAUSE FND_CHAIN
!	 TO KEEP SEARCHING), OR THE POINTER TO THE SWITCH BLOCK IF
!	 THE NAME MATCHES.
!
! SIDE EFFECTS
!
!	NONE
!
!--

    BEGIN

    MAP
	FILSW_PTR : REF FILSW_BLOCK;

    IF (CH$EQL (LEN_FSW_NAME, CH$PTR (FILSW_PTR [FSW_NAME]), LEN_FSW_NAME, CH$PTR (.SWITCH_NAME), 0))
    THEN
	.FILSW_PTR
    ELSE
	0

    END;					!OF SEL_SWITCH
END

ELUDOM
! Local Modes:
! Comment Start:!
! Comment Column:36
! Auto Save Mode:2
! Mode:Fundamental
! End: