PFSPrefixMapImpl.mesa
Copyright Ó 1989, 1990, 1991 by Xerox Corporation. All rights reserved.
Carl Hauser, September 13, 1989 4:29:06 pm PDT
Chauser, August 16, 1990 4:50 pm PDT
Willie-s, February 19, 1992 4:45 pm PST
Willie-Sue, July 20, 1990 12:05:12 pm PDT
Michael Plass, August 22, 1991 1:21 pm PDT
DIRECTORY
PFSNames,
PFSPrefixMap,
ProcessProps,
Rope
;
PFSPrefixMapImpl: CEDAR MONITOR
IMPORTS PFSNames, ProcessProps
EXPORTS PFSPrefixMap
= BEGIN OPEN PFSPrefixMap;
ROPE: TYPE = Rope.ROPE;
defaultPrefixTable: PrefixTableList ¬ NIL;
DefaultPrefixTable: PROC RETURNS [PrefixTableList] ~ {
WITH ProcessProps.GetProp[$PrefixTableList] SELECT FROM
p: PrefixTableList => RETURN [p];
ENDCASE;
RETURN [defaultPrefixTable]
};
GetMap: PUBLIC ENTRY PROC[pTable: PrefixTableList] RETURNS [el: EntryList] ~ {
IF pTable = NIL THEN pTable ¬ DefaultPrefixTable[];
FOR each: PrefixTableList ¬ pTable, each.rest WHILE each # NIL DO
el ¬ CONS[ [each.first.prefix, each.first.translation], el];
ENDLOOP;
};
SetMap: PUBLIC ENTRY PROC[map: EntryList] ~
{ defaultPrefixTable ¬ FromMapInternal[map] };
SetMapFromPTable: PUBLIC ENTRY PROC[pTable: PrefixTableList] ~
{ defaultPrefixTable ¬ pTable };
FromMapToPTable: PUBLIC ENTRY PROC[map: EntryList] RETURNS[PrefixTableList] ~
{ RETURN[FromMapInternal[map]] };
FromMapInternal: INTERNAL PROC[map: EntryList] RETURNS[pTable: PrefixTableList ¬ NIL] ~ {
FOR each: EntryList ¬ map, each.rest WHILE each # NIL DO
pTable ¬ InsertInternal[each.first.prefix, each.first.translation, NIL];
ENDLOOP;
};
Translate: PUBLIC ENTRY PROC [name: PATH, pTable: PrefixTableList] RETURNS [PATH] ~ {
Translates the name. If no translation is present, returns the original name.
ENABLE UNWIND => NULL;
len: INT ¬ -1;
entry: PrefixTableEntry ¬ [];
IF pTable = NIL THEN pTable ¬ DefaultPrefixTable[];
FOR each: PrefixTableList ¬ pTable, each.rest WHILE each # NIL DO
matchLen: INT ¬ Match[name, each.first.prefix];
IF matchLen > len THEN {
len ¬ matchLen;
entry ¬ each.first;
};
ENDLOOP;
IF ( len = -1 ) THEN RETURN[ name ];
RETURN[ PFSNames.Cat[
entry.translation,
PFSNames.SubName[name~name, start~len, directory~PFSNames.IsADirectory[name]]]
];
};
TranslateAndGetHints: PUBLIC ENTRY PROC [name: PATH, pTable: PrefixTableList]
RETURNS [PrefixTableEntry] ~ {
Translates the name. If no translation is present, returns the original name.
ENABLE UNWIND => NULL;
len: INT ¬ -1;
translatedName: PATH;
entry: PrefixTableEntry ¬ [];
IF pTable = NIL THEN pTable ¬ DefaultPrefixTable[];
FOR each: PrefixTableList ¬ pTable, each.rest WHILE each # NIL DO
matchLen: INT ¬ Match[name, each.first.prefix];
IF matchLen > len THEN {
len ¬ matchLen;
entry ¬ each.first;
};
ENDLOOP;
IF ( len = -1 ) THEN RETURN[ [
translation: name,
fsName: PFSNames.ComponentRope[PFSNames.Fetch[name, 0]],
nameOnFS: PFSNames.ReplaceComponent[name: name, index: 0, new: []],
replacedPrefix: IF name.ComponentCount[]>0 THEN name.SubName[0, 1, name.IsAbsolute[], TRUE] ELSE NIL,
suppliedPrefixLen: IF name.ComponentCount[]>0 THEN 1 ELSE 0 ]
];
translatedName ¬ PFSNames.Cat[
entry.translation,
PFSNames.SubName[name~name, start~len, directory~PFSNames.IsADirectory[name]]];
RETURN[ [
translation: translatedName,
fsName: entry.fsName,
nameOnFS: PFSNames.ReplaceComponent[name: translatedName, index: 0, new: []],
replacedPrefix: entry.prefix,
suppliedPrefixLen: entry.suppliedPrefixLen ]
];
};
Match: PROC [name, prefix: PATH] RETURNS [matchLen: INT ¬ -1] ~ {
prefixLen: CARD ¬ PFSNames.ComponentCount[prefix];
nameLen: CARD ¬ PFSNames.ComponentCount[name];
IF (prefix.IsAbsolute[] # name.IsAbsolute[]) OR (nameLen < prefixLen) THEN RETURN[ -1 ];
FOR i: CARD IN [0..prefixLen) DO
IF NOT PFSNames.EqualComponents[PFSNames.Fetch[name, i], PFSNames.Fetch[prefix, i]] THEN RETURN [-1];
ENDLOOP;
RETURN[prefixLen];
};
Lookup: PUBLIC ENTRY PROC [prefix: PATH, pTable: PrefixTableList] RETURNS [PATH] ~ {
... returns the PrefixTable entry for the given name ([NIL, NIL] if no such translation).
ENABLE UNWIND => NULL;
IF pTable = NIL THEN pTable ¬ DefaultPrefixTable[];
FOR each: PrefixTableList ¬ pTable, each.rest WHILE each # NIL DO
IF PFSNames.Equal[prefix, each.first.prefix] THEN {
RETURN[each.first.translation];
};
ENDLOOP;
RETURN [NIL];
};
Delete: PUBLIC ENTRY PROC [name: PATH, pTable: PrefixTableList]
RETURNS [existing: PATH, newPTable: PrefixTableList] ~ {
... deletes the given prefix (if any) from the map, and returns the deleted element ([NIL, NIL] if no such element).
ENABLE UNWIND => NULL;
lag: PrefixTableList ¬ NIL;
newPTable ¬ IF pTable = NIL THEN defaultPrefixTable ELSE pTable;
FOR each: PrefixTableList ¬ newPTable, each.rest WHILE each # NIL DO
IF PFSNames.Equal[name, each.first.prefix] THEN {
IF lag = NIL THEN newPTable ¬ each.rest ELSE lag.rest ¬ each.rest;
each.rest ¬ NIL;
IF ( pTable = NIL ) THEN defaultPrefixTable ¬ newPTable;
RETURN [each.first.translation, newPTable];
};
lag ¬ each;
ENDLOOP;
RETURN [NIL, newPTable];
};
InsertIntoNewPTable: PUBLIC ENTRY PROC[prefix: PATH, translation: PATH]
RETURNS[newPTable: PrefixTableList] ~
{ newPTable ¬ LIST[MakePrefixTableEntry[prefix, translation]]; };
Insert: PUBLIC ENTRY PROC [prefix: PATH, translation: PATH, pTable: PrefixTableList]
RETURNS[newPTable: PrefixTableList] ~ {
newPTable ¬ InsertInternal[prefix, translation, pTable];
IF pTable = NIL THEN defaultPrefixTable ¬ newPTable;
RETURN[newPTable];
};
InsertInternal: INTERNAL PROC [prefix: PATH, translation: PATH, pTable: PrefixTableList]
RETURNS[newPTable: PrefixTableList] ~ {
... inserts the first item in the PseudoServerList into the root PseudoServerList.
ENABLE UNWIND => NULL;
IF pTable = NIL THEN newPTable ¬ defaultPrefixTable ELSE newPTable ¬ pTable;
IF prefix#NIL THEN {
lag: PrefixTableList ¬ NIL;
newList: PrefixTableList ¬ LIST[MakePrefixTableEntry[prefix, translation]];
FOR each: PrefixTableList ¬ newPTable, each.rest WHILE each # NIL DO
SELECT PFSNames.Compare[prefix, each.first.prefix, FALSE] FROM
less => {
Insert into the new position in the list
newList.rest ¬ each;
EXIT;
};
equal => {
Insert into the new position in the list, splice out old entry
newList.rest ¬ each.rest;
EXIT;
};
ENDCASE;
lag ¬ each;
ENDLOOP;
IF lag = NIL THEN newPTable ¬ newList ELSE lag.rest ¬ newList;
};
};
MakePrefixTableEntry: PROC [prefix: PATH, translation: PATH] RETURNS[PrefixTableEntry] ~ {
RETURN[ [
prefix: prefix,
translation: translation,
fsName: PFSNames.ComponentRope[PFSNames.Fetch[translation, 0]],
suppliedPrefixLen: PFSNames.ComponentCount[translation]
] ];
};
END.