-- Match.mesa
-- modified by McCreight, September 8, 1980 4:30 PM
-- written by McCreight, May 30, 1980 6:08 PM
-- edited by Brotz, March 9, 1981 5:41 PM
DIRECTORY
MatchDefs: FROM "MatchDefs" USING [];
Match: PROGRAM IMPORTS -- nothing -- EXPORTS MatchDefs =
PUBLIC BEGIN
--
IsMatch: PROCEDURE[name,pattern:STRING] RETURNS [BOOLEAN] =
BEGIN -- does the name match the pattern?
patternPos,namePos,patternAnchor,nameAnchor:CARDINAL;
patternAnchor←0; nameAnchor←0; -- where name began matching non-* seg of pattern
patternPos←patternAnchor; namePos←nameAnchor; -- next compare position
DO -- loop for last ’* in pattern.
WHILE patternPos<pattern.length DO
SELECT TRUE FROM
(pattern[patternPos]=’*) =>
BEGIN
patternPos←patternPos+1; patternAnchor←patternPos;
nameAnchor←namePos;
END;
namePos>=name.length => RETURN[FALSE];
(pattern[patternPos]=’#) =>
BEGIN
IF patternPos#0 AND patternPos=patternAnchor
THEN -- first char(s) of * segment
{patternAnchor←patternAnchor+1; nameAnchor←namePos+1};
patternPos←patternPos+1; namePos←namePos+1;
END;
(pattern[patternPos]=’’) AND (patternPos<pattern.length-1) AND
(pattern[patternPos+1]=name[namePos]) => -- quoted character matches
{patternPos←patternPos+2; namePos←namePos+1};
pattern[patternPos]=name[namePos] => -- chars match
{patternPos←patternPos+1; namePos←namePos+1};
ENDCASE =>
BEGIN
IF patternAnchor=0 THEN RETURN[FALSE]; -- char mismatch, no pattern * thus far
patternPos←patternAnchor;
nameAnchor←nameAnchor+1; namePos←nameAnchor
END;
ENDLOOP;
IF namePos>=name.length OR
patternAnchor>=pattern.length THEN -- name finished or pattern ends with *
RETURN[TRUE];
WHILE namePos<name.length DO -- skip trailing .’s or !ddd in name
SELECT name[namePos] FROM
’. => NULL;
’! =>
BEGIN
namePos←namePos+1;
WHILE namePos<name.length DO
SELECT name[namePos] FROM
IN [’0..’9] => NULL;
ENDCASE => EXIT;
namePos←namePos+1;
ENDLOOP;
END;
ENDCASE => EXIT;
namePos←namePos+1;
REPEAT FINISHED => RETURN[TRUE]; -- Trailing stuff was harmless.
ENDLOOP;
IF patternAnchor = 0 THEN RETURN[FALSE]
ELSE {patternPos ← patternAnchor; namePos ← nameAnchor ← nameAnchor + 1};
ENDLOOP;
END; -- IsMatch
--
Capitalize: PROCEDURE[s,capS: STRING] =
BEGIN
c:CHARACTER; i:CARDINAL;
capS.length←s.length;
FOR i IN [0..s.length) DO
c←s[i];
IF c IN [’a..’z]
THEN capS[i]←c-40B
ELSE capS[i]←c;
ENDLOOP;
END;
--
UnCapitalize: PROCEDURE[s,unCapS: STRING] =
BEGIN
c:CHARACTER; i:CARDINAL;
unCapS.length←s.length;
FOR i IN [0..s.length) DO
c←s[i];
IF c IN [’A..’Z]
THEN unCapS[i]←c+40B
ELSE unCapS[i]←c;
ENDLOOP;
END;
-- Main Program
END.