MakeDoAuxImpl.Mesa
Mike Spreitzer September 4, 1986 10:56:54 pm PDT
Carl Hauser, April 11, 1985 3:43:34 pm PST
Last tweaked by Mike Spreitzer on October 5, 1992 12:00 pm PDT
Eduardo Pelegri-Llopart March 17, 1989 8:40:08 am PST
JKF January 11, 1989 10:29:32 am PST
Willie-s, February 13, 1992 6:37 pm PST
 
DIRECTORY
Basics USING [IsBound],
BasicTime USING [GetClockPulses],
Commander USING [CommandObject, Handle],
CommandTool USING [CurrentWorkingDirectory, Install],
Convert USING [RopeFromTime],
FS,
Icons USING [IconFlavor, NewIconFromFile],
IO USING [card, Close, GetChar, noInputStream, PutChar, PutF, PutFR, rope, STREAM, Value],
List USING [AList, Assoc, PutAssoc],
MakeDo,
MakeDoPrivate,
MakeDoPorting USING [logPath],
MessageWindow USING [Append, Blink],
ProcessProps USING [AddPropList, GetPropList],
RefTab,
Rope,
SymTab,
UserProfile USING [CallWhenProfileChanges, ProfileChangeReason, Token];
 
MakeDoAuxImpl: 
CEDAR 
MONITOR
IMPORTS Basics, BasicTime, CommandTool, Convert, FS, Icons, IO, List, MakeDo, MakeDoPrivate, MakeDoPorting, MessageWindow, ProcessProps, RefTab, Rope, SymTab, UserProfile
EXPORTS MakeDo, MakeDoPrivate
 =
 
BEGIN OPEN MakeDo, MakeDoPrivate;
RefTableE: TYPE = MakeDo.RefTable;
ROPE: TYPE = Rope.ROPE;
NodeRep: PUBLIC TYPE = MakeDoPrivate.NodeRep;
ActionRep: PUBLIC TYPE = MakeDoPrivate.ActionRep;
NodeClassRep: PUBLIC TYPE = MakeDoPrivate.NodeClassRep;
Warning: PUBLIC SIGNAL [message: ROPE] = CODE;
debugging: PUBLIC BOOL ← FALSE;
leafClass: ActionClass ← NEW [ActionClassRep ← []];
leaf: PUBLIC Action ← NEW [ActionRep ← [cmd: "-- leaf", class: leafClass]];
nodes: SymTab.Ref ← SymTab.Create[case: FALSE];
installationDirectory: ROPE = CommandTool.CurrentWorkingDirectory[];
defaultIconFileShortName: ROPE = "MakeDo-MTV.icons";
iconsFileName: ROPE ← NIL;
icons: PUBLIC IconSeq;
LoadIcons: 
PROC [fileName: 
ROPE] 
RETURNS [icons: IconSeq] = {
nIcons: NAT ← 0;
flavors: LIST OF Icons.IconFlavor ← NIL;
FOR nIcons ← 0, nIcons+1 
DO
flavor: Icons.IconFlavor = Icons.NewIconFromFile[fileName, nIcons];
IF flavor = unInit THEN EXIT;
flavors ← CONS[flavor, flavors];
ENDLOOP;
 
icons ← NEW [IconSeqPrivate[nIcons]];
FOR i: 
NAT 
DECREASING 
IN [0 .. icons.length) 
DO
icons[i] ← flavors.first;
flavors ← flavors.rest;
ENDLOOP;
 
IF flavors # NIL THEN ERROR;
};
 
DoInWDir: 
PROC [wDirRope: 
ROPE, inner: 
PROC] ~ {
propList: List.AList ~ List.PutAssoc[key: wDirKey, val: wDirRope, aList: NIL];
ProcessProps.AddPropList[propList: propList, inner: inner];
};
wDirKey: ATOM ~ $WorkingDirectory;
 
NoteProfile: 
PROC [reason: UserProfile.ProfileChangeReason] 
--UserProfile.ProfileChangedProc-- = {
proFileName: ROPE = UserProfile.Token["MakeDo.IconFile", defaultIconFileShortName];
Try: 
PROC [short: 
ROPE] 
RETURNS [ok: 
BOOL ← 
TRUE] ~ {
TryInWDir: 
PROC ~ {
icons ← LoadIcons[short !
FS.Error => {
ok ← FALSE;
MessageWindow.Append[Rope.Cat["Problem loading MakeDo icons from ", short], TRUE];
MessageWindow.Blink[];
CONTINUE}];
 
IF ok THEN iconsFileName ← short;
RETURN};
 
IF short.Equal[iconsFileName, FALSE] THEN RETURN;
DoInWDir[installationDirectory, TryInWDir];
RETURN};
 
IF Basics.IsBound[MessageWindow.Append] 
THEN
IF 
NOT (Try[proFileName] 
OR Try[defaultIconFileShortName]) 
THEN {
icons ← NEW [IconSeqPrivate[1]];
icons[0] ← tool;
iconsFileName ← NIL;
};
 
 
};
 
GetNode: 
PUBLIC 
ENTRY 
PROC [someName: 
ROPE, class: NodeClass, mayAdd: 
BOOL ← 
TRUE] 
RETURNS [node: Node] = {
ENABLE UNWIND => NULL;
canonicalName: ROPE ← IF class # NIL THEN class.CanonizeName[someName] ELSE someName;
IF (node ← 
NARROW[nodes.Fetch[canonicalName].val]) = 
NIL 
AND mayAdd 
THEN {
node ← NEW [NodeRep ← [given: someName, name: canonicalName, class: class, memberships: MakeRefTable[]]];
StartTime[node];
IF NOT nodes.Insert[canonicalName, node] THEN ERROR;
}
 
ELSE IF node = NIL THEN NULL
ELSE IF class # node.class THEN ERROR;
};
 
EnumerateAndDestroy: 
PUBLIC 
ENTRY 
PROC [to: 
PROC [Node], andDestroy
--table when done--: 
BOOL] = {
ENABLE UNWIND => {};
PerNode: 
PROC [key, val: 
REF 
ANY] 
RETURNS [stop: 
BOOL ← 
FALSE] 
--RefTab.EachPairAction-- = {
n: Node = NARROW[val];
to[n];
RETURN [FALSE]};
 
IF nodes.Pairs[PerNode] THEN ERROR;
IF andDestroy THEN nodes.Erase[];
};
 
IncrementStepCount: 
PUBLIC 
ENTRY 
PROC [job: Job] = {
ENABLE UNWIND => {};
job.nSteps ← job.nSteps + 1;
};
 
AddFailedCmd: 
PUBLIC 
ENTRY 
PROC [job: Job, a: Action] = {
ENABLE UNWIND => {};
job.failedSteps ← CONS[a, job.failedSteps];
};
 
MakeRefTable: 
PUBLIC 
PROC 
RETURNS [table: RefTable] =
{table ← RefTab.Create[]};
 
AddToRefTable: 
PUBLIC 
PROC [ra: 
REF 
ANY, t: RefTable] =
{IF NOT t.Insert[ra, $T] THEN ERROR; RETURN};
 
EnsureRefInTable: 
PUBLIC 
PROC [ra: 
REF 
ANY, t: RefTable] = {
[] ← t.Insert[ra, $T];
RETURN};
 
DeleteFromRefTable: 
PUBLIC 
PROC [ra: 
REF 
ANY, t: RefTable] 
RETURNS [found: 
BOOL] = {
found ← t.Delete[ra];
RETURN};
 
RefInTable: 
PUBLIC 
PROC [ra: 
REF 
ANY, t: RefTable] 
RETURNS [
BOOL] = {
RETURN [t.Fetch[ra].found]};
 
MDInstall: 
PUBLIC 
PROC [dir, packageName: 
ROPE] 
RETURNS [foundFile, failed: 
BOOL ← 
TRUE] ~ {
log: IO.STREAM ~ FS.StreamOpen[fileName: Rope.Cat[MakeDoPorting.logPath, packageName, ".InstallLog"], accessOptions: create, keep: 10];
searchRules: REF ANY ← List.Assoc[$SearchRules, GetCommanderHandle[].propertyList];
processProps: List.AList ~ List.PutAssoc[$WorkingDirectory, dir, NIL];
cmd: Commander.Handle ~ 
NEW [Commander.CommandObject ← [
in: IO.noInputStream,
out: log,
err: log,
commandLine: NIL,
propertyList: List.PutAssoc[$SearchRules, searchRules, NIL]
]];
 
Doit: PROC ~ {[foundFile, failed] ← CommandTool.Install[packageName, cmd]; RETURN};
ProcessProps.AddPropList[processProps, Doit];
log.Close[];
RETURN};
 
chKey: ATOM ← $CommanderHandle;
GetCommanderHandle: 
PUBLIC 
PROC 
RETURNS [ch: Commander.Handle] = {
ch ← NARROW[List.Assoc[chKey, ProcessProps.GetPropList[]]];
IF ch = NIL THEN ERROR;
};
 
fineTime: BOOL ← FALSE;
Log: 
PUBLIC 
PROC [fmt: 
ROPE, v1, v2, v3, v4, v5: 
IO.Value ← [null[]]] =
BEGIN
out: IO.STREAM ← GetCommanderHandle[].out;
IF fineTime THEN out.PutF["%g:", IO.card[BasicTime.GetClockPulses[]]];
out.PutF[fmt, v1, v2, v3, v4, v5];
out.PutChar['\n];
END;
 
Confirm: 
PUBLIC 
PROC [action: 
ROPE] =
BEGIN
ch: Commander.Handle = GetCommanderHandle[];
in: IO.STREAM = ch.in;
out: IO.STREAM = ch.out;
out.PutF["Ready to %g ? ", IO.rope[action]];
WHILE in.GetChar[] # '\n DO NULL ENDLOOP;
END;
 
Exists: 
PUBLIC 
PROC [n: Node, zeroLenExists: 
BOOL ← 
TRUE] 
RETURNS [exists: 
BOOL] =
{created: Time; length: INT;
[created, length] ← GetInfo[n];
RETURN [(created # notExistTime) AND (zeroLenExists OR length#0)]};
 
InnerExists: 
PUBLIC 
PROC [n: Node, zeroLenExists: 
BOOL ← 
TRUE] 
RETURNS [exists: 
BOOL] =
{created: Time; length: INT;
[created, length] ← InnerGetInfo[n];
RETURN [(created # notExistTime) AND (zeroLenExists OR length#0)]};
 
FmtTime: 
PUBLIC 
PROC [t: Time] 
RETURNS [asRope: 
ROPE] = {
asRope ← 
SELECT t 
FROM
notExistTime => "never",
unknownTime => "unknown",
ENDCASE => Convert.RopeFromTime[from: t, end: seconds, useAMPM: FALSE, includeZone: FALSE];
 
};
 
PublicPartsOfNode: 
PUBLIC 
PROC [n: Node] 
RETURNS [name: 
ROPE, class: NodeClass] = {
RETURN [
name: n.name,
class: n.class];
 
};
 
DescribeNode: 
PUBLIC 
PROC [n: Node] 
RETURNS [r: 
ROPE] = {
SELECT n.class 
FROM
fileClass => {
r ← n.name;
};
 
ENDCASE => {
r ← IO.PutFR["(%g %g)", [refAny[n.class.name]], [refAny[n.name]]];
};
 
 
};
 
PublicPartsOfAction: 
PUBLIC 
PROC [a: Action] 
RETURNS [cmd: 
ROPE, foundData: 
REF 
ANY, class: ActionClass] = {
RETURN [
cmd: a.cmd,
foundData: a.foundData,
class: a.class];
 
};
 
DestructivelyReverseActionList: 
PUBLIC 
PROC [old: ActionList] 
RETURNS [new: ActionList] = {
prev: ActionList ← NIL;
cur: ActionList ← old;
WHILE cur # 
NIL 
DO
next: ActionList ← cur.rest;
cur.rest ← prev;
prev ← cur;
cur ← next;
ENDLOOP;
 
new ← prev;
};
 
EnglishList: 
PUBLIC 
PROC [nl: NodeList] 
RETURNS [el: 
ROPE, ec: 
CARDINAL] =
BEGIN
twoOfMany: ROPE;
ec ← 0;
FOR nl ← nl, nl.rest 
WHILE nl # 
NIL 
DO
SELECT ec 
FROM
=0 => el ← nl.first.name;
=1 => {
twoOfMany ← nl.first.name.Cat[", and ", el];
el ← nl.first.name.Cat[" and ", el];
};
 
=2 => el ← nl.first.name.Cat[", ", twoOfMany];
>2 => el ← nl.first.name.Cat[", ", el];
ENDCASE => ERROR;
 
ec ← ec + 1;
ENDLOOP;
 
END;
 
IsNode: 
PUBLIC 
PROC [ra: 
REF 
ANY] 
RETURNS [
BOOL] =
{RETURN [ISTYPE[ra, Node]]};
 
NarrowToNode: 
PUBLIC 
PROC [ra: 
REF 
ANY] 
RETURNS [Node] =
{RETURN[NARROW[ra]]};
 
IsAction: 
PUBLIC 
PROC [ra: 
REF 
ANY] 
RETURNS [
BOOL] =
{RETURN [ISTYPE[ra, Action]]};
 
NarrowToAction: 
PUBLIC 
PROC [ra: 
REF 
ANY] 
RETURNS [Action] =
{RETURN[NARROW[ra]]};
 
IsNodeClass: 
PUBLIC 
PROC [ra: 
REF 
ANY] 
RETURNS [
BOOL] =
{RETURN [ISTYPE[ra, NodeClass]]};
 
NarrowToNodeClass: 
PUBLIC 
PROC [ra: 
REF 
ANY] 
RETURNS [NodeClass] =
{RETURN[NARROW[ra]]};
 
UserProfile.CallWhenProfileChanges[NoteProfile];
END.