VersionMapDefaultsImpl.mesa
Copyright © 1984, 1985 by Xerox Corporation. All rights reserved.
Russ Atkinson (RRA) August 7, 1985 10:03:59 pm PDT
DIRECTORY
BasicTime USING [GMT],
BcdDefs USING [VersionStamp],
DefaultRemoteNames USING [Get],
FS USING [Error, ExpandName],
Rope USING [Concat, Equal, ROPE],
UserProfile USING [CallWhenProfileChanges, ListOfTokens, ProfileChangedProc],
VersionMap USING [Map, MapAndName, MapList, RestoreMapFromFile, VersionToName],
VersionMapDefaults USING [];
VersionMapDefaultsImpl: CEDAR MONITOR
IMPORTS DefaultRemoteNames, 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: BOOLTRUE;
root: EntryList ← NIL;
EntryList: TYPE = LIST OF Entry;
Entry: TYPE = RECORD [key: ATOMNIL, mapList: VersionMap.MapList ← NIL];
defaultSourceName: ROPE ← Rope.Concat[DefaultRemoteNames.Get[].current, "VersionMap>CedarSource.VersionMap"];
defaultSymbolsName: ROPE ← Rope.Concat[DefaultRemoteNames.Get[].current, "VersionMap>CedarSymbols.VersionMap"];
FileNameFromVersion: PUBLIC PROC [which: ATOM, version: BcdDefs.VersionStamp] RETURNS [name: ROPENIL, created: BasicTime.GMT] = {
... 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 {
mapAndName: VersionMap.MapAndName ← VersionMap.VersionToName[mapList, version];
name ← mapAndName.name;
created ← mapAndName.created;
};
};
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: ROPENIL;
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 ← defaultSourceName;
$Symbols => mapFileName ← defaultSymbolsName;
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", defaultSymbolsName];
ProcessUserProfileList[$Source, "VersionMap.SourceMaps", defaultSourceName];
};
ProcessUserProfileList: PROC [class: ATOM, key: ROPE, always: ROPE] = {
list: LIST OF ROPE ← UserProfile.ListOfTokens[key, NIL];
always ← FS.ExpandName[always ! FS.Error => CONTINUE].fullFName;
FOR each: LIST OF ROPE ← list, each.rest WHILE each # NIL DO
each.first ← FS.ExpandName[each.first ! FS.Error => CONTINUE].fullFName;
Try to make the name canonical in form
ENDLOOP;
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 => CONTINUE];
IF map # NIL THEN AddToMapList[class, map];
};
RemoveRope: PROC [list: LIST OF ROPE, item: ROPE] RETURNS [LIST OF ROPE] = {
lag: LIST OF ROPENIL;
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.