<> <> <> DIRECTORY Basics, BasicTime, CedarProcess, Commander, CommandTool, Convert, FS, Icons, IO, List, MakeDo, MakeDoPrivate, MessageWindow, ProcessProps, RedBlackTree, Rope, UserProfile; MakeDoAuxImpl: CEDAR MONITOR IMPORTS BasicTime, CommandTool, Convert, FS, Icons, IO, List, MakeDo, MakeDoPrivate, MessageWindow, ProcessProps, RedBlackTree, Rope, UserProfile EXPORTS MakeDo, MakeDoPrivate <> <> <> = BEGIN OPEN MakeDo, MakeDoPrivate; 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; leaf: PUBLIC Action _ NEW [ActionRep _ [cmd: "-- leaf", class: leafClass]]; leafClass: ActionClass _ NEW [ActionClassRep _ []]; nodes: RedBlackTree.Table _ RedBlackTree.Create[IdGetKey, CompareNodes]; installationDirectory: ROPE = CommandTool.CurrentWorkingDirectory[]; defaultIconFileShortName: ROPE = "MakeDo.Icons"; defaultIconFileName: ROPE = FS.ExpandName[defaultIconFileShortName, installationDirectory].fullFName; iconsFileName: ROPE; 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; }; Fullize: PROC [short: ROPE] RETURNS [full: ROPE] = { full _ NIL; full _ FS.FileInfo[name: short, wDir: installationDirectory !FS.Error => CONTINUE].fullFName; full _ full}; NoteProfile: PROC [reason: UserProfile.ProfileChangeReason] --UserProfile.ProfileChangedProc-- = { proFileName: ROPE = UserProfile.Token["MakeDo.IconFile", defaultIconFileShortName]; fullFileName: ROPE _ NIL; fullFileName _ Fullize[proFileName]; IF fullFileName = NIL THEN { MessageWindow.Append[Rope.Cat["MakeDo icons file ", proFileName, " not found (relative to ", installationDirectory, ")"], TRUE]; MessageWindow.Blink[]; fullFileName _ Fullize[defaultIconFileShortName]; }; IF fullFileName # NIL AND NOT fullFileName.Equal[iconsFileName, FALSE] THEN { ok: BOOL _ TRUE; icons _ LoadIcons[fullFileName !FS.Error => { ok _ FALSE; MessageWindow.Append[Rope.Cat["Problem loading MakeDo icons from ", fullFileName], TRUE]; MessageWindow.Blink[]; CONTINUE}]; IF ok THEN iconsFileName _ fullFileName; }; IF icons = NIL THEN { icons _ NEW [IconSeqPrivate[1]]; icons[0] _ tool; iconsFileName _ NIL; }; }; CompareNodes: PUBLIC PROC [k, data: REF ANY] RETURNS [Basics.Comparison] --RedBlackTree.Compare-- = BEGIN GetKey: PROC [ra: REF] RETURNS[r: ROPE] = { r _ WITH ra SELECT FROM n: Node => n.name, x: ROPE => x, ENDCASE => ERROR}; k1: ROPE _ GetKey[k]; k2: ROPE _ GetKey[data]; RETURN [k1.Compare[s2: k2, case: FALSE]]; END; 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.Lookup[canonicalName]]) = NIL AND mayAdd THEN { node _ NEW [NodeRep _ [name: canonicalName, class: class, memberships: MakeRefTable[]]]; StartTime[node]; nodes.Insert[node, node]; } ELSE IF node = NIL THEN NULL ELSE IF class # node.class THEN ERROR; }; EnumerateNodes: PUBLIC ENTRY PROC [to: PROC [Node], andDestroy--table when done--: BOOL] = { ENABLE UNWIND => {}; PerNode: PROC [data: REF ANY] RETURNS [stop: BOOL _ FALSE] --RedBlackTree.EachNode-- = { n: Node = NARROW[data]; to[n]; }; nodes.EnumerateIncreasing[PerNode]; IF andDestroy THEN nodes.DestroyTable[]; }; 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 _ RedBlackTree.Create[IdGetKey, CompareRefs]}; AddToRefTable: PUBLIC PROC [ra: REF ANY, t: RefTable] = {t.Insert[ra, ra]}; EnsureRefInTable: PUBLIC PROC [ra: REF ANY, t: RefTable] = { IF t.Lookup[ra] = ra THEN RETURN; t.Insert[ra, ra]; }; DeleteFromRefTable: PUBLIC PROC [ra: REF ANY, t: RefTable] RETURNS [found: REF ANY] = { n: RedBlackTree.Node = t.Delete[ra]; RETURN [IF n # NIL THEN n.data ELSE NIL]; }; IdGetKey: PROC [data: REF ANY] RETURNS [REF ANY] --RedBlackTree.GetKey-- = {RETURN[data]}; CompareRefs: PROC [k, data: REF ANY] RETURNS [Basics.Comparison] --RedBlackTree.Compare-- = TRUSTED BEGIN k1: INT _ LOOPHOLE[k]; k2: INT _ LOOPHOLE[data]; RETURN [SELECT k1 FROM < k2 => less, = k2 => equal, > k2 => greater, ENDCASE => ERROR]; END; 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] RETURNS [exists: BOOL] = {exists _ GetCreated[n] # notExistTime}; InnerExists: PUBLIC PROC [n: Node] RETURNS [exists: BOOL] = {exists _ InnerGetCreated[n] # notExistTime}; 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] = { RETURN [ cmd: a.cmd, foundData: a.foundData]; }; 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.