Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-08 - 43,50512/doswit.b36
There are no other files named doswit.b36 in the archive.
MODULE DOSWITCHES=
!Process a collection of switches or commands from a string
!Uses TABLELOOK and standard TOPS-20 command table
BEGIN
!
! Table of Contents
!
FORWARD ROUTINE
DOSWITCHES,
DOCMDS,	!Process a bunch of commands in a line of input
CHKDELIM, !Determine if a character is a delimiter
RDATOM;	!Get the next collection of alphanumerics

!
! REQUIRE & LIBRARY declarations
!
LIBRARY 'TBL';

!
! Version info
!
THIS_IS [DOSW] VERSION [1] EDIT [3] DATE [13,FEB,78]

!
! Literals
!
LITERAL
	NULL=0,
	BELL=7,
	LF=%O'12',
	VT=%O'13',
	FORM=%O'14',
	CR=%O'15',
	CNTRLZ=%O'32',
	ESC=%O'33';
!
! Externals
!
EXTERNAL ROUTINE
TABLELOOK;

!
! Macros
!
MACRO
	DELIMCHAR=DELIM<0,7>%,	!Arbitrary delimiter character
	DELIMCRLF=DELIM<7,1>%,	!CR & LF
	DELIMESC=DELIM<8,1>%,	!ESC
	DELIMALLCTL=DELIM<9,1>%,!All normal terminating controls
	DELIMSPACE=DELIM<10,1>%;!Accept space
!
! Routines
!

GLOBAL ROUTINE DOSWITCHES(TBL,PTR,ARGS)=
!Process switches in a string
!TBL: Address of TOPS-20 format command table
!PTR: ADDRESS OF byte pointer to string (returned updated)
!ARGS: Additional arguments to pass to switch processing routines
!	See DOCMDS for details
BEGIN
LOCAL V;
SELECTONE (V=DOCMDS(.TBL,.PTR,%C'/',.ARGS)) OF SET
[ILLCMD]:	RETURN ILLSWI;
[AMBCMD]:	RETURN AMBSWI;
[OTHERWISE]:	RETURN .V;
TES;
END;	!DOSWITCHES


GLOBAL ROUTINE DOCMDS(TBL,PTR,DELIM,ARGS)=
!Process commands in a string
!TBL: Address of TOPS-20 format command table
!PTR: ADDRESS OF byte pointer to string (returned updated)
!DELIM: Decoded as follows
!	.DELIM<0,7> =  ASCII character used as command separator
!	.DELIM<7,1> = Accept CR & LF as delimiters also (CRLF is treated as LF)
!	.DELIM<8,1> = Accept ESC as delimiter
!	.DELIM<9,1> = Accept above plus VT,BELL,FORM,^Z
!	.DELIM<10,1> = Accept SPACE as delimiter
!ARGS: Address of vector of additional arguments to switch processing routines
!	ARGS[0] = # of such args, ARGS[1 to n] contain the arguments
!Switch processing routines are called with 2 arguments:
!	[1] Address of byte pointer to rest of command string
!	[2] Address of vector of additional arguments (described above)
BEGIN
LOCAL RETVAL: BITVECTOR[16];
LOCAL C;	!Last character read
LOCAL V;	!Value (from TABLEL) of last switch atom read
LOCAL ATOM: VECTOR[CH$ALLOCATION(20)]; !Store last atom read

RETVAL=0;	!Start with nothing
WHILE (C=CH$RCHAR(..PTR)) EQL %C' ' DO CH$RCHAR_A(.PTR);!Eat spaces
DO	BEGIN
	CHKDELIM(.PTR,.DELIM);		 !Eat delim if not done already
	.PTR=RDATOM(..PTR,CH$PTR(ATOM));	!Read next atom
	IF CH$RCHAR(CH$PTR(ATOM)) EQL 0 THEN RETURN 0; !You get nothing for nothing
	V=TABLELOOK(.TBL,ATOM);
	CASE .V FROM 0 TO 1 OF SET
	[0]:	RETURN ILLCMD;	!Illegal command
	[1]:	RETURN AMBCMD;	!Ambiguous
	[OUTRANGE]:;		!OK
	TES;
	SELECTONE .(.V)<RH> OF SET
	[0 TO 15]:	RETVAL[.(.V)<RH>]=1;	!Set a bit
	[OTHERWISE]:	(..V)(.PTR,.ARGS);	!Call a routine
	TES;
	WHILE (C=CH$RCHAR(..PTR)) EQL %C' ' DO CH$RCHAR_A(.PTR);!Eat spaces
	END WHILE (CHKDELIM(.PTR,.DELIM));
				!As long as we keep getting what we want
.RETVAL
END;!DOCMD
ROUTINE CHKDELIM(PTR,DELIM)=
!Determine if a character pointed to by byte pointer is a delimiter
!PTR: Address of byte pointer (returned updated past delimiter, if any)
!DELIM: A delimiter specifier:
!	.DELIM<0,7> =  ASCII character used as command separator
!	.DELIM<7,1> = Accept CR & LF as delimiters also (CRLF is treated as LF)
!	.DELIM<8,1> = Accept ESC as delimiter
!	.DELIM<9,1> = Accept above plus VT,BELL,FORM,^Z
!	.DELIM<10,1> = Accept SPACE as delimiter
BEGIN
LOCAL CHAR;

SELECT (CHAR=CH$RCHAR(..PTR)) OF SET
[.DELIMCHAR]:	(CH$RCHAR_A(.PTR);RETURN WIN);	!Matched specific delimiter
[LF]:	IF (.DELIMCRLF OR .DELIMALLCTL) THEN (CH$RCHAR_A(.PTR);RETURN WIN);
[CR]: IF (.DELIMCRLF OR .DELIMALLCTL) THEN
		BEGIN
		IF CH$A_RCHAR(.PTR) EQL LF	!Eat CR
			THEN CH$RCHAR_A(.PTR);	!CRLF so eat both
		RETURN WIN
		END;
[ESC]: IF (.DELIMESC OR .DELIMALLCTL) THEN
		(CH$RCHAR_A(.PTR);RETURN WIN);
[VT,BELL,FORM,CNTRLZ]: IF .DELIMALLCTL THEN (CH$RCHAR_A(.PTR);RETURN WIN);
[%C' ']:	IF .DELIMSPACE THEN
		 (CH$RCHAR_A(.PTR);RETURN WIN);
[OTHERWISE]:	0;
TES;
END; !CHKDELIM
GLOBAL ROUTINE RDATOM(SPTR,DPTR)=
!Copy characters from SPTR to DPTR until a non-filename character is read
!Return updated value of SPTR as value
!DPTR: destination byte pointer
!SPTR: source byte pointer
BEGIN
REGISTER C;	!Last character
REGISTER OSPTR;	!Old value of SPTR

DO	BEGIN
	OSPTR=.SPTR;
	C=CH$RCHAR_A(SPTR);
	SELECT .C OF SET
	[%C'a' TO %C'z']: C=.C-32;	!Convert to lower case
	[%C'A' TO %C'Z',%C'0' TO %C'9',%C'a' TO %C'z']:
		CH$WCHAR_A(.C,DPTR);	!Save the character
	[OTHERWISE]: (CH$WCHAR_A(0,DPTR);RETURN .OSPTR); !Return ptr to break character
	TES;
	END WHILE 1;

END; !RDATOM
END ELUDOM