DIRECTORY Basics USING [IsBound], BasicTime USING [GetClockPulses], Commander USING [CommandObject, Handle], CommanderOps USING [DoCommand], Convert USING [RopeFromTime], FileNames USING [CurrentWorkingDirectory], FS, Icons USING [IconFlavor, NewIconFromFile], IO USING [card, Close, GetChar, noInputStream, PutChar, PutF1, PutFL, PutFR, rope, STREAM, Value], List USING [AList, Assoc, PutAssoc], MakeDo, MakeDoPrivate USING [Action, ActionRep, IconSeq, IconSeqPrivate, Job, Node, NodeClass, NodeClassRep, NodeList, NodeRep, StartTime], MakeDoPorting USING [logPath], ProcessProps USING [AddPropList, GetPropList], RefTab, Rope, SimpleFeedback USING [Append, Blink], SymTab, UserProfile USING [CallWhenProfileChanges, ProfileChangeReason, Token]; MakeDoAuxImpl: CEDAR MONITOR IMPORTS Basics, BasicTime, CommanderOps, Convert, FileNames, FS, Icons, IO, List, MakeDo, MakeDoPrivate, MakeDoPorting, ProcessProps, RefTab, Rope, SimpleFeedback, 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 = FileNames.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; SimpleFeedback.Append[$MakeDo, oneLiner, $info, Rope.Concat["Problem loading MakeDo icons from ", short]]; SimpleFeedback.Blink[$MakeDo, $info]; CONTINUE}]; IF ok THEN iconsFileName ¬ short; RETURN}; IF short.Equal[iconsFileName, FALSE] THEN RETURN; DoInWDir[installationDirectory, TryInWDir]; RETURN}; IF Basics.IsBound[Icons.NewIconFromFile] 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 ~ { failed ¬ CommanderOps.DoCommand[Rope.Concat[ "Install ", packageName ], cmd] = $Failure; 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.PutF1["%g:", IO.card[BasicTime.GetClockPulses[]]]; out.PutFL[fmt, LIST[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.PutF1["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. Ί MakeDoAuxImpl.Mesa Copyright Σ 1991 by Xerox Corporation. All rights reserved. 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 6, 1992 11:19 am PDT Eduardo Pelegri-Llopart March 17, 1989 8:40:08 am PST JKF January 11, 1989 10:29:32 am PST Willie-s, April 10, 1992 4:34 pm PDT Michael Plass, November 27, 1991 10:38 am PST INVARIANT Job node table Κ η–(cedarcode) style•NewlineDelimiter ™code™Kšœ Οeœ1™Kšœ5™5K™$K™$K™-—K˜šž ˜ Kšœžœ ˜Kšœ žœ˜!Kšœ žœ˜(Kšœ žœ ˜Kšœžœ˜Kšœ žœ˜*Kšžœ˜Kšœžœ˜*KšžœžœKžœ ˜bKšœžœ˜$K˜Kšœžœp˜ƒKšœžœ ˜Kšœ žœ˜.Kšœ˜Kšœ˜Kšœžœ˜%K˜Kšœ žœ6˜G—K˜šΡbnx œžœž˜Kšžœ6žœ žœm˜·Kšžœ˜šž ™ K™K™ —Kšœ˜—K˜Kšžœžœ˜!K˜Kšœ žœ˜"Kšžœžœžœ˜Kšœ žœžœ˜-Kšœ žœžœ˜1Kšœžœžœ˜7K˜Kš Οnœžœžœ žœžœ˜.K˜Kšœ žœžœžœ˜K˜Kšœžœ˜3K˜Kšœžœ žœ2˜KK˜Kšœ(žœ˜/Kšœžœ'˜BKšœžœ˜4K˜Kšœžœžœ˜Kšœžœ ˜K˜š  œžœ žœžœ˜=Kšœžœ˜Kšœ žœžœžœ˜(šžœž˜KšœC˜CKšžœžœžœ˜Kšœ žœ˜ Kšžœ˜—Kšœžœ˜%š žœžœž œžœž˜/Kšœ˜K˜Kšžœ˜—Kšžœ žœžœžœ˜K˜—K˜š œžœ žœ žœ˜0KšœIžœ˜NKšœ;˜;Kšœ˜Kšœ žœ˜"—K˜š  œžœ+Οc"œ˜bKšœ žœB˜Sš  œžœ žœžœžœžœ˜5š  œžœ˜šœžœ ˜&Kšœžœ˜ Kšœj˜jKšœ%˜%Kšžœ˜ —Kšžœžœ˜!Kšžœ˜—Kšžœžœžœžœ˜1Kšœ+˜+Kšžœ˜—šžœ'ž˜-šžœžœžœ žœ˜AKšœžœ˜ Kšœ˜Kšœžœ˜K˜——K˜—K˜š œžœžœžœ žœžœžœžœ˜kKšžœžœžœ˜Kš œžœžœ žœžœžœ ˜Uš žœ žœ$žœžœžœ˜JKšœžœ_˜iK˜Kšžœžœ#žœžœ˜4Kšœ˜—Kš žœžœžœžœž˜Kšžœžœžœžœ˜&Kšœ˜—K˜š œžœžœžœžœ‘œžœ˜aKšžœžœ˜š œžœ žœžœžœžœžœ‘œ˜\Kšœ žœ˜K˜Kšžœžœ˜—Kšžœžœžœ˜#Kšžœ žœ˜!K˜—K˜š œžœžœžœ˜4Kšžœžœ˜Kšœ˜K˜—K˜š  œžœžœžœ˜9Kšžœžœ˜Kšœžœ˜+K˜—K˜š  œžœžœžœ˜5Kšœ˜—K˜š   œžœžœžœžœ˜7Kš œžœžœžœžœžœ˜-—K˜š  œžœžœžœžœ˜