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