VersionMapDefaultsImpl.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Russ Atkinson, October 29, 1984 1:06:32 pm PST
Paul Rovner, August 19, 1983 1:17 pm
DIRECTORY
BcdDefs USING [VersionStamp],
FS USING [Error],
Rope USING [Equal, ROPE],
UserProfile USING [CallWhenProfileChanges, ListOfTokens, ProfileChangedProc],
VersionMap USING [Map, MapList, RestoreMapFromFile, VersionToName],
VersionMapDefaults USING [];
VersionMapDefaultsImpl:
CEDAR
MONITOR
IMPORTS FS, Rope, UserProfile, VersionMap
EXPORTS VersionMapDefaults
= BEGIN OPEN Rope;
Operations on default version map lists.
WhichMapList:
TYPE =
ATOM;
$Source => the source symbol version map list (initially from CedarSource.VersionMap)
$Symbols => the source symbol version map list (initially from CedarSymbols.VersionMap)
other => a user-defined version map variety (initially empty)
assumeImmutable: BOOL ← TRUE;
root: EntryList ← NIL;
EntryList: TYPE = LIST OF Entry;
Entry: TYPE = RECORD [key: ATOM ← NIL, mapList: VersionMap.MapList ← NIL];
FileNameFromVersion:
PUBLIC
PROC
[which: ATOM, version: BcdDefs.VersionStamp] RETURNS [name: ROPE ← NIL] = {
... returns a name corresponding to the given version stamp in the indicated map list (does not check for multiple names, since that is the responsibility of the version map creator).
mapList: VersionMap.MapList ← GetMapList[which];
IF mapList #
NIL
THEN
name ← VersionMap.VersionToName[mapList, version].name;
};
GetMapList:
PUBLIC
ENTRY
PROC
[which: ATOM] RETURNS [list: VersionMap.MapList ← NIL] = {
... gets the current selected version map list. If there is no such map, then NIL will be returned unless which = $Source or which = $Symbols, which will restore the official version maps from CedarSource.VersionMap or CedarSymbols.VersionMap respectively.
ENABLE UNWIND => NULL;
mapFileName: ROPE ← NIL;
FOR eList: EntryList ← root, eList.rest
WHILE eList #
NIL
DO
IF eList.first.key = which THEN RETURN [eList.first.mapList];
ENDLOOP;
SELECT which
FROM
$Source => mapFileName ← "///CedarSource.VersionMap";
$Symbols => mapFileName ← "///CedarSymbols.VersionMap";
ENDCASE => RETURN;
list ← LIST[VersionMap.RestoreMapFromFile[mapFileName, TRUE]];
root ← CONS[Entry[which, list], root];
};
AddToMapList:
PUBLIC
ENTRY
PROC [which:
ATOM, map: VersionMap.Map] = {
... adds a new map to the lookup list. Use this proc for adding personal version maps.
ENABLE UNWIND => NULL;
mapList: VersionMap.MapList ← LIST[map];
IF map = NIL THEN RETURN;
FOR eList: EntryList ← root, eList.rest
WHILE eList #
NIL
DO
IF eList.first.key = which
THEN {
mapList.rest ← eList.first.mapList;
eList.first.mapList ← mapList;
RETURN};
ENDLOOP;
There is no mapList under this key, so add it
root ← CONS[Entry[which, mapList], root];
};
SetMapList:
PUBLIC
ENTRY
PROC [which:
ATOM, list: VersionMap.MapList ←
NIL] = {
.. sets the current version map for source files. Since there can be a race between GetMapList and SetMapList, this operation should not be casually used!
ENABLE UNWIND => NULL;
FOR eList: EntryList ← root, eList.rest
WHILE eList #
NIL
DO
IF eList.first.key = which
THEN {
eList.first.mapList ← list;
RETURN};
ENDLOOP;
There is no mapList under this key, so add it
root ← CONS[Entry[which, list], root];
};
ProcessUserProfile: UserProfile.ProfileChangedProc = {
ProcessUserProfileList[$Symbols, "VersionMap.SymbolsMaps", "///CedarSymbols.VersionMap"];
ProcessUserProfileList[$Source, "VersionMap.SourceMaps", "///CedarSource.VersionMap"];
};
ProcessUserProfileList:
PROC [class:
ATOM, key:
ROPE, always:
ROPE] = {
list: LIST OF ROPE ← UserProfile.ListOfTokens[key, NIL];
list ← RemoveRope[list, always];
SetMapList[class, NIL];
ProcessAName[class, always];
WHILE list #
NIL
DO
name: ROPE = list.first;
list ← RemoveRope[list, name];
ProcessAName[class, name];
ENDLOOP;
};
ProcessAName:
PROC [class:
ATOM, name:
ROPE] = {
map: VersionMap.Map ← NIL;
map ← VersionMap.RestoreMapFromFile[name
! FS.Error => IF error.group # bug THEN CONTINUE];
IF map # NIL THEN AddToMapList[class, map];
};
RemoveRope:
PROC [list:
LIST
OF
ROPE, item:
ROPE]
RETURNS [
LIST
OF
ROPE] = {
lag: LIST OF ROPE ← NIL;
FOR each:
LIST
OF
ROPE ← list, each.rest
WHILE each #
NIL
DO
IF Rope.Equal[each.first, item,
FALSE]
THEN {
IF lag = NIL THEN list ← each.rest ELSE lag.rest ← each.rest;
LOOP;
};
lag ← each;
ENDLOOP;
RETURN [list];
};
UserProfile.CallWhenProfileChanges[ProcessUserProfile];
END.