Trailing-Edge
-
PDP-10 Archives
-
decuslib10-08
-
43,50512/wild.b36
There are no other files named wild.b36 in the archive.
MODULE WILD=
!Routines to do wildcarding
!Currently does not include directory searching stuff
BEGIN
FORWARD ROUTINE
CKWLD, !Routine to check a filespec against a wildcarded filespec
CKWLD6, !Routine to check a sixbit word against one containing wildcards
CKWLDM, !Check 2 words using a mask
CKWLDD, !Check a directory specification
CKWLDU, !Check a UFD specification
CKWLDA, !Check 2 ASCIZ strings
MSKW6; !Build a mask for wildcard (sixbit) characters
LIBRARY 'TBL';
THIS_IS[WILD] VERSION[1] EDIT[2] DATE[1,FEB,78]
GLOBAL ROUTINE CKWLD(WILDFB,FB)=
!Check the possibly wildcarded filespec in WILDFB against the filespec in FB
!Return 1 if they match, 0 otherwise
!ARGUMENTS: FB: a fileblock
! WILDFB: a fileblock which may contain wildcards
BEGIN
MAP FB: REF FILE_BLOCK,
WILDFB: REF FILE_BLOCK;
IF CKWLD6(.WILDFB[FILE$NAME],.FB[FILE$NAME])
AND CKWLD6(.WILDFB[FILE$EXTENSION],.FB[FILE$EXTENSION])
AND CKWLD6(.WILDFB[FILE$DEVICE],.FB[FILE$DEVICE])
AND CKWLDD(.WILDFB[FILE$LPPN],.FB[FILE$LPPN])
THEN 1 ELSE 0
END; !CKWLD
GLOBAL ROUTINE CKWLD6(WILDSIX,SIX)=
!Check a wildcard sixbit word against an ordinary one.
!Return 1 if they match, 0 otherwise
!ARGUMENTS: WILDSIX, a SIXBIT word with wild characters possibly
! SIX, a SIXBIT word
BEGIN
IF ((.WILDSIX XOR .SIX) AND MSKW6(.WILDSIX)) EQL 0 THEN 1 ELSE 0
END; !CKWLD6
GLOBAL ROUTINE CKWLDD(WILDD,D)=
!Check a directory specifier which may contain wildcards (WILDD)
!against one that doesn't (D).
!WILDD & D are either PPNs or addresses of PATH blocks
BEGIN
MAP WILDD: REF VECTOR; !If this is a pathblock address
MAP D: REF VECTOR; ! " " " " "
LOCAL PPNMASK;
LOCAL SFDLVL;
LOCAL U,WILDU;
LITERAL PATH_UFD=2, PATH_SFDS=3;
IF (.WILDD<LH> EQL 0) THEN
BEGIN !WILDD is an addr of a path block
IF (.D<LH> NEQ 0) THEN !D is a PPN, not an addr of a path block
BEGIN
IF (CKWLDU(.WILDD[PATH_UFD],.D) AND (.WILDD[PATH_SFDS] EQL 0))
THEN RETURN 1 ELSE RETURN 0;
!Compare a PPN with a path block.
!The path block must only contain a UFD
END
ELSE BEGIN !Path blocks for both arguments
IF (CKWLDU(.WILDD[PATH_UFD],.D[PATH_UFD]) EQL 0) THEN RETURN 0;
INCR SFDLVL FROM PATH_SFDS TO PATH_SFDS+SFDMAX-1 DO
BEGIN
IF CKWLD6(.WILDD[.SFDLVL],.D[.SFDLVL]) EQL 0
THEN RETURN 0;
IF .WILDD[.SFDLVL] EQL 0 THEN RETURN 1;
END;
RETURN 1;
END
END
ELSE BEGIN !WILDD was a PPN
IF .D<LH> EQL 0 THEN !D was a path block
BEGIN
IF (CKWLDU(.WILDD,.D[PATH_UFD]) AND (.D[PATH_SFDS] EQL 0))
THEN RETURN 1 ELSE RETURN 0;
END
ELSE BEGIN !Both arguments were PPNs
CKWLDU(.WILDD,.D)
END
END
END; !CKWLDD
GLOBAL ROUTINE CKWLDM(U1,U2,WMASK)=
!Compare 2 words using WMASK as the mask for wildcards
((.U1 AND .WMASK) EQL (.U2 AND .WMASK));
GLOBAL ROUTINE CKWLDU(WILDU,U)=
!Compare a wildcarded UFD against a UFD without wildcards
!WILDU is a UFD that may contain wildcards, U is the other UFD
!Return 1 if they match, 0 otherwise
BEGIN
LOCAL MASK;
MASK<LH>=(IF .WILDU<LH> EQL %O'777777' THEN 0 ELSE %O'777777');
MASK<RH>=(IF .WILDU<RH> EQL %O'777777' THEN 0 ELSE %O'777777');
CKWLDM(.WILDU,.U,.MASK)
END;
GLOBAL ROUTINE CKWLDA(WPTR,PTR)=
!Check 2 ASCIZ strings for wildcard match as follows:
!% or ? match 'A'-'Z','0'-'9','_'
!* matches any number of the above
![,(,< match any of [,<,( and ],>,) match any of ],>,)
!WPTR: byte pointer to string containing wildcards
!PTR: byte pointer to other string
!Returns: 1 if match, 0 if not
BEGIN
LITERAL LOSE=0, WIN=1;
MACRO FILENAME_CHARS=%C'A' TO %C'Z',%C'0' TO %C'9',%C'_'%;
MACRO TERMINATORS=0,%O'15',%O'12',%O'127',%O'33',%C'/',%C'='%;
LOCAL WC, !Last char read through WPTR
C; !Last char read through PTR
DO BEGIN
SELECTONE (WC=CH$RCHAR_A(WPTR)) OF SET
[%C'<',%C'(',%C'[']: !Some kind of bracket
BEGIN
SELECTONE (C=CH$RCHAR_A(PTR)) OF SET
[%C'<',%C'(',%C'[']:; !OK
[OTHERWISE]: RETURN LOSE; !No match
TES;
END;
[%C'>',%C')',%C']']: !Some kind of close bracket
BEGIN
SELECTONE (C=CH$RCHAR_A(PTR)) OF SET
[%C'>',%C')',%C']']:; !OK
[OTHERWISE]: RETURN LOSE; !No match
TES;
END;
[%C'%',%C'?']: !Single charcter wildcard
SELECTONE (CH$RCHAR(.PTR)) OF SET
[FILENAME_CHARS]:
CH$RCHAR_A(PTR); !Match anything
[OTHERWISE]:; !or nothing
TES;
[%C'*']:
BEGIN
DO BEGIN
IF CKWLDA(.WPTR,.PTR) THEN RETURN WIN;
SELECTONE CH$RCHAR_A(PTR) OF SET
[FILENAME_CHARS]:;
[OTHERWISE]: RETURN LOSE;
TES;
END WHILE 1;
END;
[TERMINATORS]: !End of the string
SELECTONE CH$RCHAR_A(PTR) OF SET
[TERMINATORS]: RETURN WIN; !Both strings ended
[OTHERWISE]: RETURN LOSE; !no match
TES;
[OTHERWISE]:
IF CH$RCHAR_A(PTR) NEQ .WC THEN RETURN LOSE; !Char didn't match
TES;
END WHILE 1;
END; !CKWLDA
GLOBAL ROUTINE MSKW6(SIXWORD)=
!Return a mask of the sixbit wildcard characters in SIXWORD
!This is of the format: %O'77' in each non-wildcard position,
! and %O'00' in each wildcarded position
BEGIN
LOCAL MASK; !Mask for wildcarded characters
MASK=-1; !Start out assuming no wildcards at all
DECR P FROM 30 TO 0 BY 6 DO
BEGIN
IF .SIXWORD<.P,6> EQL (%C'?'-%O'40') THEN MASK<.P,6>=0;
IF .SIXWORD<.P,6> EQL (%C'*'-%O'40') THEN
BEGIN
MASK<0,(.P+6)>=0;
EXITLOOP
END;
END;
.MASK
END; !MSKW6
END ELUDOM