DIRECTORY Atom, Basics USING [IsBound], BasicTime USING [GMT, Period, ToNSTime], FileNames USING [CurrentWorkingDirectory], FS USING [ComponentPositions, Error, ExpandName, StreamOpen], IO, MakeDo USING [Action, ActionClass, ActionClassRep, AddFinder, fileClass, From, GetNode, GetProp, InnerGetCreated, Node, NodeList, notExistTime, PublicPartsOfAction, PublicPartsOfNode, SetProp, Time, Warning], MakeDoParsers, MakeDoPrivate USING [MDInstall], MakeDoPorting USING [logPath], MobDefs USING [Base, FTHandle, FTIndex, FTNull, FTRecord, FTSelf, MobBase, NameRecord, NameString, NullVersion, VersionID, VersionStamp], Mobery USING [FlushCache, StampAndNameFromFile], MobListerUtils USING [FreeMob, MobErr, PrintVersion, ReadMob], RefTab, Rope, SimpleFeedback, UserProfile USING [CallWhenProfileChanges, ProfileChangedProc, Boolean]; MimosaAndCinderDeps: CEDAR MONITOR IMPORTS Atom, Basics, BasicTime, FileNames, FS, IO, MakeDo, MakeDoParsers, MakeDoPrivate, MakeDoPorting, Mobery, MobListerUtils, RefTab, Rope, SimpleFeedback, UserProfile = BEGIN OPEN MakeDo, MDPs:MakeDoParsers; ShouldNotHappen: ERROR = CODE; ROPE: TYPE = Rope.ROPE; CachedMobData: TYPE = REF CachedMobDataRep; CachedMobDataRep: TYPE = RECORD [ created: BasicTime.GMT, stamp: MobDefs.VersionStamp, sourceStamp: MobDefs.VersionStamp, dependList: RefTab.Ref ]; SourceData: TYPE = REF SourceDataRep; SourceDataRep: TYPE = RECORD [ mobName, cName, shortName: ROPE, sourceType: SourceType ¬ Unknown, resultType: ResultType ¬ Unknown, supports: RefTab.Ref, mesaNode, cedarNode, configNode, sourceNode, switchesNode, mobNode, cNode: Node, sourceStamp, mobStamp: MobDefs.VersionStamp ¬ MobDefs.NullVersion, mobCreateTime, cCreateTime: BasicTime.GMT, mobReadable, cReadable: BOOL ¬ FALSE, supportsInvalid: BOOL ¬ FALSE, cmd: ROPE ¬ NIL ]; SourceType: TYPE = MDPs.SourceType[Unknown .. Config]; ResultType: TYPE = MDPs.ResultType[Unknown .. MobOnly]; Support: TYPE = REF SupportRep; SupportRep: TYPE = RECORD [ node: Node, version: MobDefs.VersionStamp]; installDir: ROPE ~ FileNames.CurrentWorkingDirectory[]; installed, badInstall: BOOL ¬ FALSE; dolog: BOOL ¬ FALSE; myRouterName: ATOM ~ Atom.MakeAtom["MakeDo.MimosaAndCinderDeps"]; cinderDefaultSwitch: ROPE ¬ " -m~g "; -- used to be /l - bj mimosaDefaultSwitch: ROPE ¬ " -kc "; cTail: ROPE = ".c2c.c"; cTailLength: CARDINAL = cTail.Length[]; mobExt: ROPE = "mob"; mobTail: ROPE = Rope.Concat[".", mobExt]; mesaTail: ROPE = ".mesa"; cedarTail: ROPE = ".cedar"; configTail: ROPE = ".config"; switchesTail: ROPE = ".switches"; MimosaAndCinderClass: ActionClass ¬ NEW [ActionClassRep ¬ [ CheckConsistency: CheckConsistency, Rederive: RederiveSource, EnumHiddenDeps: EnumHiddenDeps, ClearCaches: ClearCaches ]]; ClearCaches: PROC [ac: ActionClass] ~ { Mobery.FlushCache[]; MDPs.FlushCache[]; installed ¬ badInstall ¬ FALSE; }; SourceFind: PROC [resultName: ROPE, finderData: REF ANY] RETURNS [found: BOOLEAN, sought: Node, makes, cmdFrom: NodeList, from: From, cmd: ROPE, class: ActionClass, foundData: REF ANY] -- FinderProc -- ~ { mobExpanded, baseName, shortName, mobName, cName: ROPE; mobCP: FS.ComponentPositions; mobNode, cNode: Node; isMob, isC2C: BOOL ¬ FALSE; md: SourceData; found ¬ TRUE; IF badInstall THEN {found ¬ FALSE; RETURN}; [mobExpanded, mobCP, ] ¬ FS.ExpandName[resultName !FS.Error => {found ¬ FALSE; CONTINUE}]; IF NOT found THEN RETURN; isMob ¬ mobExpanded.EqualSubstrs[start1: mobCP.ext.start, len1: mobCP.ext.length, s2: mobExt, case: FALSE]; IF mobCP.ext.start + mobCP.ext.length >= cTailLength THEN { isC2C ¬ mobExpanded.EqualSubstrs[start1: mobCP.ext.start+mobCP.ext.length-cTailLength, len1: cTailLength, s2: cTail, case: FALSE]; } ELSE { isC2C ¬ FALSE; }; IF NOT (found ¬ isMob OR isC2C) THEN RETURN; IF NOT installed THEN InstallMe[]; found ¬ NOT badInstall; IF NOT found THEN RETURN; baseName ¬ mobExpanded.Substr[start: 0, len: mobCP.base.start + mobCP.base.length]; shortName ¬ mobExpanded.Substr[start: mobCP.base.start, len: mobCP.base.length]; IF isC2C THEN { baseName ¬ Rope.Substr[baseName, 0, baseName.Length[]-(cTailLength-2)]; shortName ¬ Rope.Substr[shortName, 0, shortName.Length[]-(cTailLength-2)]; }; mobNode ¬ GetNode[mobName ¬ Rope.Concat[baseName, mobTail], fileClass]; cNode ¬ GetNode[cName ¬ Rope.Concat[baseName, cTail], fileClass]; foundData ¬ md ¬ NEW [SourceDataRep ¬ [ mobName: mobName, cName: cName, shortName: shortName, supports: RefTab.Create[], mesaNode: GetNode[baseName.Concat[mesaTail], fileClass], cedarNode: GetNode[baseName.Concat[cedarTail], fileClass], configNode: GetNode[baseName.Concat[configTail], fileClass], cNode: cNode, sourceNode: NIL, switchesNode: GetNode[mobName.Concat[switchesTail], fileClass], mobNode: mobNode, mobCreateTime: MakeDo.notExistTime, cCreateTime: MakeDo.notExistTime ]]; cmdFrom ¬ LIST[md.cedarNode, md.mesaNode, md.configNode, md.switchesNode]; sought ¬ IF isC2C THEN md.cNode ELSE md.mobNode; class ¬ MimosaAndCinderClass; [from, cmd] ¬ RederiveWork[md]; makes ¬ LIST[md.cNode, md.mobNode]; RETURN}; GetSwitches: PROC [mobName: ROPE, default: ROPE ¬ NIL] RETURNS [switches: ROPE] = BEGIN ss: IO.STREAM ¬ NIL; ss ¬ FS.StreamOpen[Rope.Concat[mobName, switchesTail] !FS.Error => CONTINUE]; IF ss = NIL THEN RETURN [default]; [] ¬ ss.SkipWhitespace[]; IF ss.EndOf[] THEN { ss.Close[]; RETURN [default] } ; switches ¬ ss.GetTokenRope[IO.IDProc].token; ss.Close[]; END; SupportIsLoaded: PROC [] RETURNS [BOOL] ~ INLINE { moberies: BOOL; moblisteries: BOOL; moberies ¬ Basics.IsBound[LOOPHOLE[Mobery.StampAndNameFromFile]]; moblisteries ¬ Basics.IsBound[LOOPHOLE[MobListerUtils.PrintVersion]] AND Basics.IsBound[LOOPHOLE[MobListerUtils.ReadMob]]; RETURN [moberies AND moblisteries]; }; InstallMe: PROC ~ { foundFile, failed: BOOL; IF SupportIsLoaded[] THEN { installed ¬ TRUE; RETURN; }; [foundFile, failed] ¬ MakeDoPrivate.MDInstall[installDir, "MimosaAndCinderDepsSupport"]; badInstall ¬ failed OR NOT foundFile; installed ¬ TRUE; IF NOT foundFile THEN Warning[Rope.Cat["Couldn't install MimosaAndCinder support because couldn't find ", installDir, "MimosaAndCinderDepsSupport.Install (see ", MakeDoPorting.logPath, "MimosaAndCinderDepsSupport.InstallLog); proceeding without knowledge of MimosaAndCinder"]] ELSE IF failed THEN Warning[Rope.Cat["Couldn't install MimosaAndCinder support because of error in install file (", installDir, "MimosaAndCinderDepsSupport.Install) (see ", MakeDoPorting.logPath, "MimosaAndCinderDepsSupport.InstallLog); proceeding without knowledge of MimosaAndCinder"]]; RETURN}; CheckConsistency: PROC [a: Action, result: Node] RETURNS [consistent: BOOL, reason: ROPE] --ConsistencyChecker-- ~ { md: SourceData = NARROW[a.PublicPartsOfAction[].foundData]; switchesCreate: BasicTime.GMT = InnerGetCreated[md.switchesNode]; resultName: ROPE ~ result.PublicPartsOfNode[].name; resultCreateTime: Time = InnerGetCreated[result]; resultExists: BOOL ~ resultCreateTime # MakeDo.notExistTime; curMobStamp: MobDefs.VersionStamp; -- Stamp from the current Mob file of the action -- supportFound: BOOL ¬ FALSE; seekMob: BOOL ~ result = md.mobNode; seekC: BOOL ~ result = md.cNode; CheckSupport: PROC [key, val: REF ANY] RETURNS [stop: BOOL ¬ FALSE] --RefTab.EachPairAction-- ~ { s: Support = NARROW[val]; thisTime: Time = InnerGetCreated[s.node]; thisMobStamp: MobDefs.VersionStamp = CurMobStamp[s.node]; thisName: Rope.ROPE ~ s.node.PublicPartsOfNode[].name; extension, fullName: Rope.ROPE; cp: FS.ComponentPositions; [fullFName: fullName, cp: cp] ¬ FS.ExpandName[thisName ! FS.Error => { ERROR ShouldNotHappen}]; extension ¬ Rope.Substr[fullName, cp.ext.start, cp.ext.length]; SELECT TRUE FROM Rope.Equal[s1: extension, s2: mobExt, case: FALSE] => { IF thisMobStamp = MobDefs.NullVersion THEN RETURN [FALSE]; supportFound ¬ TRUE; IF NOT resultExists THEN RETURN [supportFound]; IF thisMobStamp # s.version THEN { out: IO.STREAM ¬ IO.ROS[]; out.PutRope["last used version "]; TRUSTED {MobListerUtils.PrintVersion[s.version, out, FALSE]}; out.PutF1[ " of %g, but current version is ", [rope[thisName]] ]; TRUSTED {MobListerUtils.PrintVersion[thisMobStamp, out, FALSE]}; consistent ¬ FALSE; reason ¬ out.RopeFromROS[]; RETURN [TRUE]; } ELSE RETURN [NOT resultExists]; }; ENDCASE => { IF thisTime = MakeDo.notExistTime THEN RETURN [FALSE]; supportFound ¬ TRUE; IF NOT resultExists THEN RETURN [supportFound]; IF BasicTime.Period[thisTime, resultCreateTime] < 0 THEN { out: IO.STREAM ¬ IO.ROS[]; out.PutRope["File created in "]; TRUSTED {MobListerUtils.PrintVersion[MobStampFromTime[resultCreateTime], out, TRUE]}; out.PutF1[ " but %g was created in ", [rope[thisName]] ]; TRUSTED {MobListerUtils.PrintVersion[MobStampFromTime[thisTime], out, TRUE]}; consistent ¬ FALSE; reason ¬ out.RopeFromROS[]; RETURN [TRUE]; } ELSE RETURN [NOT resultExists]; }; }; UpdateSupport[md]; SELECT md.sourceType FROM Mesa, Config => NULL; Unknown => RETURN [TRUE, "No source is known for this result"]; ENDCASE => ERROR ShouldNotHappen; IF md.resultType = MobOnly AND seekC THEN IF md.cCreateTime = MakeDo.notExistTime THEN RETURN [TRUE, "no amount of recompilation will derive a .c2c.c file from a .mesa interface"] ELSE RETURN [FALSE, "C2C file should not exist for a .mesa interface"]; SELECT TRUE FROM seekC => IF resultExists AND NOT md.cReadable THEN RETURN [FALSE, "c not readable"]; seekMob => IF resultExists AND NOT md.mobReadable THEN RETURN [FALSE, "mob not readable"]; ENDCASE => ERROR ShouldNotHappen; {curSourceStamp: MobDefs.VersionStamp ~ CurSourceStamp[md.sourceNode]; IF curSourceStamp # MobDefs.NullVersion THEN { supportFound ¬ TRUE; IF md.mobReadable AND resultExists AND curSourceStamp # md.sourceStamp THEN { out: IO.STREAM ¬ IO.ROS[]; out.PutRope["last used source "]; TRUSTED {MobListerUtils.PrintVersion[md.sourceStamp, out, TRUE]}; out.PutRope[", but current source is "]; TRUSTED {MobListerUtils.PrintVersion[curSourceStamp, out, TRUE]}; RETURN [FALSE, out.RopeFromROS[]]; }; }; }; curMobStamp ¬ CurMobStamp[md.mobNode]; IF seekMob AND resultExists THEN { IF curMobStamp = MobDefs.NullVersion THEN RETURN [FALSE, "New compiler version"]; }; IF seekC AND resultExists THEN { IF md.mobStamp # MobDefs.NullVersion THEN { IF curMobStamp # md.mobStamp THEN { out: IO.STREAM ¬ IO.ROS[]; out.PutRope["last used mob "]; TRUSTED {MobListerUtils.PrintVersion[md.mobStamp, out, TRUE]}; out.PutRope[", but current mob is "]; TRUSTED {MobListerUtils.PrintVersion[curMobStamp, out, TRUE]}; RETURN [FALSE, out.RopeFromROS[]]; }; } ELSE { IF BasicTime.Period[md.cCreateTime, md.mobCreateTime] > 0 THEN RETURN [FALSE, "C2C is older than MobFile file"]; } }; IF switchesCreate # MakeDo.notExistTime THEN { supportFound ¬ TRUE; IF BasicTime.Period[resultCreateTime, switchesCreate] > 0 THEN RETURN [FALSE, IO.PutFR1["switches file created later than result %g", [rope[resultName]]]]; }; consistent ¬ TRUE; reason ¬ "all version stamps match"; [] ¬ md.supports.Pairs[CheckSupport]; IF NOT supportFound THEN RETURN [TRUE, "no inputs exist"]; IF NOT resultExists THEN RETURN [FALSE, IO.PutFR1["some inputs exist, but not output %g", [rope[resultName]]]]; RETURN}; UpdateSupport: PROC [md: SourceData] = { oldMob: Time = md.mobCreateTime; oldC: Time = md.cCreateTime; md.mobCreateTime ¬ InnerGetCreated[md.mobNode]; md.cCreateTime ¬ InnerGetCreated[md.cNode]; IF md.mobCreateTime = MakeDo.notExistTime THEN RETURN; IF md.mobCreateTime = oldMob AND md.cCreateTime = oldC AND NOT md.supportsInvalid THEN RETURN; MakeSupports[md]; }; CurSourceStamp: PROC [node: Node] RETURNS [mobStamp: MobDefs.VersionStamp] = BEGIN time: Time ¬ InnerGetCreated[node]; RETURN [MobStampFromTime[time]]; END; MobStampFromTime: PROC [time: Time] RETURNS [mobStamp: MobDefs.VersionStamp] = BEGIN mobStamp ¬ MobDefs.NullVersion; IF time = MakeDo.notExistTime THEN RETURN [mobStamp]; mobStamp[0] ¬ BasicTime.ToNSTime[time]; END; CurMobStamp: PROC [node: Node] RETURNS [stamp: MobDefs.VersionStamp] ~ { sr: CachedMobData ¬ CurMobData[node]; RETURN [sr.stamp]; }; CurMobData: ENTRY PROC [node: Node] RETURNS [sr: CachedMobData] = BEGIN ENABLE UNWIND => {}; sr: CachedMobData ¬ NARROW[node.GetProp[$MobData]]; created: BasicTime.GMT ¬ InnerGetCreated[node]; mob: MobDefs.MobBase ¬ NIL; IF sr = NIL THEN node.SetProp[ prop: $MobData, val: sr ¬ NEW [CachedMobDataRep ¬ [ created: notExistTime, stamp: MobDefs.NullVersion, sourceStamp: MobDefs.NullVersion, dependList: RefTab.Create[]]] ]; IF created = sr.created THEN RETURN [sr]; sr.created ¬ created; IF created = MakeDo.notExistTime THEN { sr.stamp ¬ MobDefs.NullVersion; sr.sourceStamp ¬ MobDefs.NullVersion; sr.dependList ¬ RefTab.Create[]; } ELSE TRUSTED { fileName: ROPE ~ node.PublicPartsOfNode[].name; mob ¬ MobListerUtils.ReadMob[fileName ! MobListerUtils.MobErr => CONTINUE]; IF mob = NIL OR mob.versionIdent # MobDefs.VersionID THEN { sr.stamp ¬ MobDefs.NullVersion; sr.sourceStamp ¬ MobDefs.NullVersion; sr.dependList ¬ RefTab.Create[]; } ELSE { InsertInDependList: PROC [name: ROPE, version: MobDefs.VersionStamp] = TRUSTED { extName: ROPE = FS.ExpandName[Rope.Concat[name, mobTail]].fullFName; node: Node = GetNode[extName, fileClass]; s: Support ¬ NARROW[sr.dependList.Fetch[node].val]; IF s # NIL THEN s.version ¬ version ELSE { s ¬ NEW [SupportRep ¬ [node, version]]; IF NOT sr.dependList.Insert[node, s] THEN ERROR; }; RETURN}; sr.stamp ¬ mob.version; sr.sourceStamp ¬ mob.sourceVersion; EnumerateFiles[mob: mob, to: InsertInDependList]; }; IF mob # NIL THEN MobListerUtils.FreeMob[mob]; }; RETURN [sr]; END; EnumerateFiles: PROC [mob: MobDefs.MobBase, to: PROC [name: ROPE, version: MobDefs.VersionStamp]] = TRUSTED BEGIN fti: MobDefs.FTIndex ¬ MobDefs.FTIndex.FIRST; ssb: MobDefs.NameString = LOOPHOLE[mob + mob.ssOffset.units]; ftb: MobDefs.Base = LOOPHOLE[mob + mob.ftOffset.units]; UNTIL fti = mob.ftLimit DO SELECT fti FROM MobDefs.FTNull => NULL; MobDefs.FTSelf => NULL; ENDCASE => { ftr: MobDefs.FTHandle = @ftb[fti]; name: ROPE = NameToRope[ftr.name, ssb]; to[name: name, version: ftr.version]}; fti ¬ fti + MobDefs.FTRecord.SIZE; IF LOOPHOLE[fti, CARD] > LOOPHOLE[mob.ftLimit, CARD] THEN ERROR; ENDLOOP; END; NameToRope: PROC [n: MobDefs.NameRecord, ssb: MobDefs.NameString] RETURNS [ROPE] = TRUSTED { CharSeq: TYPE = RECORD[PACKED SEQUENCE COMPUTED CARDINAL OF CHAR]; ss: LONG POINTER TO CharSeq = LOOPHOLE[ssb]; index: CARDINAL = n+4; len: CARDINAL = ss[index]-0C; ros: IO.STREAM = IO.ROS[]; FOR i: NAT IN [index+1..index+len] DO IO.PutChar[ros, ss[i]]; ENDLOOP; RETURN [IO.RopeFromROS[ros]]; }; MakeSupports: PROC [md: SourceData] = { NoteSupport: PROC [key, val: REF ANY] RETURNS [stop: BOOL ¬ FALSE] = --RefTab.EachPairAction-- { mobSupport: Support = NARROW[val]; node: Node = mobSupport.node; version: MobDefs.VersionStamp ~ mobSupport.version; s: Support = NARROW[md.supports.Fetch[node].val]; IF s # NIL THEN s.version ¬ version; RETURN}; stamp: MobDefs.VersionStamp; name: ROPE; md.sourceStamp ¬ MobDefs.NullVersion; { sr: CachedMobData ¬ CurMobData[md.mobNode]; IF sr.created = notExistTime THEN { md.mobReadable ¬ FALSE; md.cReadable ¬ FALSE; RETURN; }; md.sourceStamp ¬ sr.sourceStamp; md.mobReadable ¬ TRUE; IF sr.dependList.Pairs[NoteSupport] THEN ERROR; }; md.cReadable ¬ TRUE; [stamp: stamp, name: name] ¬ Mobery.StampAndNameFromFile[md.cName! FS.Error => {md.cReadable ¬ FALSE; Log["C file %g not readable (1)\n", [rope[md.cName]] ]; CONTINUE}]; IF NOT md.cReadable THEN RETURN; IF NOT Rope.Equal[name, md.shortName] THEN { md.cReadable ¬ FALSE; Log["name %g is different from expected %g\n", IO.rope[name], IO.rope[md.shortName]]; }; IF NOT md.cReadable THEN RETURN; md.mobStamp ¬ stamp; md.supportsInvalid ¬ FALSE; RETURN}; EnumHiddenDeps: PROC [a: Action, Consume: PROC [Node]] = { md: SourceData ~ NARROW[a.PublicPartsOfAction[].foundData]; CheckSupport: PROC [key, val: REF ANY] RETURNS [stop: BOOL ¬ FALSE] --RefTab.EachPairAction-- ~ { mobSupport: Support = NARROW[val]; node: Node = mobSupport.node; IF NOT md.supports.Fetch[node].found THEN Consume[node]; RETURN}; SELECT md.sourceType FROM Mesa => NULL; Config => RETURN; ENDCASE => ERROR; { sr: CachedMobData ¬ CurMobData[md.mobNode]; IF sr.created = notExistTime THEN { RETURN; }; IF sr.dependList.Pairs[CheckSupport] THEN ERROR; }; RETURN}; RederiveSource: PROC [a: Action] RETURNS [from: From, cmd: ROPE] --RederiveProc-- = { md: SourceData ~ NARROW[a.PublicPartsOfAction[].foundData]; RETURN RederiveWork[md]}; RederiveWork: PROC [md: SourceData] RETURNS [from: From, cmd: ROPE] ~ { NoteDep: PROC [fileName: ROPE] ~ { n: Node = GetNode[fileName, fileClass]; s: Support ¬ NARROW[md.supports.Fetch[n].val]; IF s = NIL THEN { s ¬ NEW [SupportRep ¬ [n, MobDefs.NullVersion]]; IF NOT md.supports.Insert[n, s] THEN ERROR; }; from.mustHave ¬ CONS[n, from.mustHave]; RETURN}; switches: Rope.ROPE; exists: BOOL; dbxDebug: BOOL = UserProfile.Boolean[key: "MakeDo.dbxDebug", default: FALSE]; from ¬ [mustHave: NIL, optional: LIST[md.switchesNode]]; md.supports.Erase[]; md.sourceNode ¬ md.mesaNode; md.sourceType ¬ Mesa; [exists: exists, resultType: md.resultType] ¬ EnumerateDependancies[md.mesaNode, Mesa, NoteDep]; IF exists THEN NULL ELSE { [exists: exists, resultType: md.resultType] ¬ EnumerateDependancies[md.cedarNode, Mesa, NoteDep]; IF exists THEN NULL ELSE { [exists: exists, resultType: md.resultType] ¬ EnumerateDependancies[md.configNode, Config, NoteDep]; IF exists THEN { md.sourceNode ¬ md.configNode; md.sourceType ¬ Config; } ELSE { md.sourceType ¬ Unknown; md.resultType ¬ Unknown; }}}; md.supportsInvalid ¬ TRUE; UpdateSupport[md]; from.mustHave ¬ CONS[md.sourceNode, from.mustHave]; SELECT md.sourceType FROM Mesa => { switches ¬ GetSwitches[md.mobName, mimosaDefaultSwitch]; cmd ¬ Rope.Cat["Mimosa ", IF dbxDebug THEN "-a " ELSE NIL, switches, " ", md.shortName]; }; Config => { switches ¬ GetSwitches[md.mobName, cinderDefaultSwitch]; cmd ¬ Rope.Cat["Cind ", switches, " ", md.shortName]; }; Unknown => cmd ¬ NIL; ENDCASE => ERROR ShouldNotHappen; md.cmd ¬ cmd; RETURN}; EnumerateDependancies: PROC [sourceNode: Node, sourceType: SourceType, consume: PROC [fileName: ROPE]] RETURNS [exists: BOOLEAN, resultType: ResultType ¬ Unknown] ~ { pd: MDPs.ParseData ~ MDPs.GetParseData[sourceNode, sourceType]; IF pd=NIL THEN RETURN [FALSE, Unknown]; MDPs.EnumerateWithSuffix[pd.refdModules, ".mob", consume]; RETURN [TRUE, pd.resultType]}; Log: PROC [fmt: ROPE, v1, v2: IO.Value ¬ [null[]] ] ~ { IF NOT dolog THEN RETURN; SimpleFeedback.PutFL[myRouterName, oneLiner, $Log, fmt, LIST[v1, v2]]; RETURN}; OnProfileChange: UserProfile.ProfileChangedProc ~ { dolog ¬ UserProfile.Boolean[key: "MimosaAndCinderDeps.Talk", default: FALSE]; }; AddFinder[["Mimosa and Cinder", SourceFind], front]; UserProfile.CallWhenProfileChanges[OnProfileChange]; END. ά MimosaAndCinderDeps.Mesa Copyright Σ 1988, 1991, 1992 by Xerox Corporation. All rights reserved. Eduardo Pelegri-Llopart, December 12, 1989 1:00:30 pm PST After ConfigAndMesaDeps.mesa Deals with Mimosa and Cinder. Output files are .mob and .c2c.c Bill Jackson (bj) January 16, 1989 1:33:06 pm PST Last tweaked by Mike Spreitzer on December 18, 1990 7:35 am PST JKF January 11, 1989 10:22:44 am PST Willie-s, September 27, 1991 2:44 pm PDT Michael Plass, November 27, 1991 10:34 am PST Doug Wyatt, March 11, 1992 1:45 pm PST INVARIANT StampRef in node props date when the information was obtained stamp of the mob stamp of the source file it depends on files (name+version) that this mob object depends on (same type as Support) sourceStamp is the desired stamp encoded in the Mob file mobStamp is the desired stamp encoded in the C file (currently unused) A description of the properties of a Mob file that will support our action. Constants A FinderProc looks for an action that will make an object with name resultName. It returns an indication of whether it found it, a pointer to the node describing the object, and a list of the nodes produced by the action. cmdFrom is a list of the determiners, while from is a list of all the nodes needed by the action to be runnable, discriminating between mandatory and optional nodes. FoundData is a record holding all the useful information that may be needed later. The action found by this finder is "MimosaAndCinder", selecting which one is to be used is done every time RederiveWork is called. We only know what to do with .Mob and .C2C.C files. Compensate for the cTail; this is a superset of the truth, but it works if we are careful elsewhere. We have to do this because actions, and Makes, are fixed. LOOPHOLE only needed for PrincOps Is an action a consistent with a current result? The action is derived from the current determiners and result is in Makes of the action. What to check depends on what we have available. for .MOBs, look inside and get the version stamp, for other lesser files, we currently have to rely on their creation date. Use the version stamp Only data available is the creation time Since createtime is non-null. Check the VersionStamp Chek the Creation Date Update the information that may have changed since last time. If the mobCreateTime is the same as before and supportsInvalid is FALSE, then no need to. Fake a version stamp for a source file out of its creation date. A MobStamp from a time Find the version stamp of this Mob file. Extract information (Stamps and Create times) from the Mobs that currently exist. It does not change the contents of md.support, which is done in RederiveWork[]. The next two procs are global because the Cedar compilers do not let me assign non-local procedure values to variables with the same scope (blah!). RederiveWork determines which of a collection of actions implied by md is currently favored by the state of the system. It returns the action and the list of all the nodes needed for this action to be startable. Collect one more dependency into the from set; also reconstructs md.support. This is adding the files to the set on which the output nodes depend on. Temporarily... SELECT md.resultType FROM Unknown, MobAndC => NULL; MobOnly => cmd ¬ Rope.Cat[cmd, "; Delete ", md.shortName, cTail]; ENDCASE => ERROR; If sourceNode exists, then callback to consume with all the fileNames that are required to be present by the semantics of sourceType and the contents of sourceNode. Caching is done. Κψ•NewlineDelimiter –(cedarcode) style™code™Kšœ Οeœ=™HKšœ9™9K™K™?Kšœ1™1Kšœ?™?KšΟkœ!™$K™(K™-K™&K™—šž ˜ Kšœ˜Kšœžœ ˜Kšœ žœžœ˜(Kšœ žœ˜*Kšžœžœ5˜=Kšžœ˜KšœžœΔ˜ΠK˜Kšœžœ ˜ Kšœžœ ˜Kšœžœ|˜‰Kšœžœ$˜0Kšœžœ*˜>Kšœ˜Kšœ˜Kšœ˜Kšœ žœ7˜H—K˜šΡbnxœžœž˜"Kšžœ%žœžœz˜¬šž ™ Kšœ™——K˜Kšžœžœ Οnœ˜&K˜KšΡblnœΠksΟsœ£’œ˜K˜Kšžœžœžœ˜K˜š œžœžœ%žœžœ˜Mšœžœ˜K™&—˜K™—˜"K™&—šœ˜K™KK˜—K˜—š œ žœžœžœžœ˜DKšœžœ˜ K˜!K˜"Kšœ˜K˜PšœB˜BK™8Kšœ4™F—Kšœ&žœ˜*Kšœžœžœ˜%Kšœžœžœ˜Kšœžœž˜K˜—K˜Kšœ žœ&˜6Kšœ žœ'˜7K˜š œ žœžœžœžœ˜;K˜ šœ˜KšœK™K——K˜Kšœ žœ'˜7Kšœžœžœ˜$K˜Kšœžœžœ˜Kšœžœ/˜Ahead™ KšΟbœžœ Οc˜;Kš€œžœ ˜$K˜Kšœžœ ˜Kšœ žœ˜'Kšœžœ ˜Kšœ žœ˜)Kšœ žœ ˜Kšœ žœ ˜Kšœ žœ ˜Kšœžœ˜!—K˜K˜š œžœ˜;Kš œ˜#Kš œ˜Kš œ˜Kš  œ ˜K˜—K˜š  œžœ˜'K˜Kšœ˜Kšœžœ˜K˜—K˜š  œžœžœžœžœžœ žœ;žœ!žœžœ₯œ˜ΝKš œ+œ œœ%œΘ™ΨK™ƒKšœ2žœ˜7Kšœžœ˜Kšœ˜Kšœžœžœ˜K˜Kšœžœ˜ Kšžœ žœ žœžœ˜+Kš œžœžœžœžœ˜ZKšžœžœžœžœ˜Kšœdžœ˜kšžœ2˜4šžœ˜Kšœ{žœ˜‚—šœžœ˜Kšœžœ˜Kšœ˜——š žœžœžœžœžœ˜,KšΡjls'›p ¦ ™3—K™Kšžœžœ žœ ˜"Kšœžœ ˜Kšžœžœžœžœ˜KšœS˜SKšœP˜Pšžœžœ˜K™K˜GKšœJ˜JKšœ˜—KšœG˜GKšœA˜Ašœžœ˜'Kšœ˜K˜ Kšœ˜Kšœ˜Kšœ8˜8Kšœ:˜:Kšœ<˜K˜%Kšžœ0žœ˜>Kšžœžœ˜"K˜—Kšœ˜—šžœ˜K™Kšžœ8žœžœžœ$˜pK˜——Kšœ˜—šžœ&žœ˜.Kšœžœ˜Kš žœ8žœžœžœžœK˜›Kšœ˜—Kšœ žœ˜Kšœ$˜$Kšœ%˜%Kš žœžœžœžœžœ˜:Kš žœžœžœžœžœžœE˜oKšžœ˜—K˜š  œžœ˜(KšœF œœžœ™˜Kšœ ˜ Kšœ˜Kšœ/˜/K˜+Kšžœ(žœžœ˜6Kš žœžœžœžœžœžœ˜^Kšœ˜K˜—K˜š œžœžœ#˜LK™@Kšž˜Kšœ#˜#Kšžœ˜ —Kšžœ˜K˜š œžœžœ#˜NK™Kšž˜Kšœ˜Kšžœžœžœ ˜5Kšœ'˜'—Kšžœ˜K˜š  œžœžœ"˜HK˜%Kšžœ ˜K˜K˜—š€ œžœžœžœ˜AK™(Kšž˜Kšžœžœ˜Kšœžœ˜3Kšœžœ˜/Kšœžœ˜šžœžœžœ˜Kšœ˜šœ žœ˜#Kšœ˜Kšœ˜Kšœ!˜!Kšœ˜—K˜—Kšžœžœžœ˜)K˜šžœ˜ šžœ˜Kšœ˜Kšœ%˜%Kšœž˜ K˜—šžœžœ˜Kšœ žœ!˜/KšœAžœ˜Kšžœžœžœ%˜4šžœ˜Kšœ˜Kšœ%˜%Kšœž˜ K˜—šžœ˜š€œžœžœ#žœ˜PKšœ žœžœ2˜DK˜)Kšœ žœ ˜3šžœž˜ Kšžœ˜šžœ˜Kšœžœ ˜'Kšžœžœžœžœ˜0K˜——Kšžœ˜—Kšœ˜Kšœ#˜#Kšœ1˜1K˜——Kšžœžœžœ˜.K˜——Kšžœ˜ Kšžœ˜—K˜š  œžœžœžœ$ž˜kKšž˜Kšœ'žœ˜-Kšœžœ˜=Kšœžœ˜7šžœž˜šžœž˜Kšœžœ˜Kšœžœ˜šžœ˜ Kšœ"˜"Kšœžœ˜'K˜&——Kšœžœ˜"Kšžœžœžœžœžœžœžœ˜@Kšžœ˜—Kšžœ˜K˜—š   œžœ2žœžœžœ˜\Kšœ žœžœžœžœžœžœžœžœ˜BKš œžœžœžœ žœ˜,Kšœžœ˜Kšœžœ˜Kš œžœžœžœžœ˜šžœžœžœž˜%Kšžœ˜Kšžœ˜—Kšžœžœ˜K˜K˜—š  œžœ˜'Kšœv œ™’š  œžœ žœžœžœžœžœ₯œ˜`Kšœžœ˜"K˜Kšœ3˜3Kšœ žœ˜1Kšžœžœžœ˜$Kšžœ˜—K˜Kšœžœ˜ K˜Kšœ%˜%˜K˜+šžœžœ˜#Kšœžœ˜Kšœžœ˜Kšžœ˜K˜—K˜ Kšœžœ˜Kšžœ"žœžœ˜/K˜—Kšœžœ˜KšœCžœžœ:žœ˜©Kšžœžœžœžœ˜ šžœžœ˜%šžœ˜Kšœžœ˜Kšœ/žœ žœ˜UK˜——Kšžœžœžœžœ˜ K˜Kšœžœ˜Kšžœ˜—K˜š œžœ  œžœ ˜:Kšœžœ$˜;š  œžœ žœžœžœžœžœ₯œ˜aKšœžœ˜"K˜Kšžœžœžœ˜8Kšžœ˜—šžœž˜Kšœžœ˜ Kšœ žœ˜Kšžœžœ˜—˜K˜+šžœžœ˜#Kšžœ˜K˜—Kšžœ#žœžœ˜0K˜—Kšžœ˜K˜—š  œžœ žœžœ₯œ˜UKšœžœ$˜;Kšžœ˜—K˜K™“K™š  œžœžœžœ˜GKšœDœƒ œ™Τš œžœ žœ˜"Kšœ%œ ™MKšœ'˜'Kšœ žœ˜.šžœžœžœ˜Kšœžœ)˜0šžœžœžœžœ˜+K™H—K˜—Kšœžœ˜'Kšžœ˜—Kšœžœ˜Kšœžœ˜ Kšœ žœ8žœ˜MKšœžœ žœ˜8K˜K˜Kšœ˜Kšœ˜Kšœ`˜`Kšžœžœž˜Kšžœ˜Kšœa˜aKšžœžœž˜Kšžœ˜Kšœd˜dšžœžœ˜Kšœ˜Kšœ˜Kšœ˜—šžœ˜Kšœ˜Kšœ˜Kšœ˜—K˜Kšœžœ˜Kšœ˜Kšœžœ˜3šžœž˜šœ ˜ Kšœ#€œ˜8Kš€™Kš œžœ žœžœžœ˜XšΠkyΟyͺ™Kš«ͺ«™Kš«A™AKšͺ«ͺ«™—Kšœ˜—šœ ˜ Kšœ#€œ˜8Kšœ5˜5Kšœ˜—Kšœžœ˜Kšžœžœ˜!—K˜ Kšžœ˜—K˜š  œžœ5žœ žœžœ žœ'˜¦Kš œ œœ  œ6 œ œ™ΆK˜?Kš žœžœžœžœžœ ˜'K˜:Kšžœžœ˜—K˜š œžœžœ žœ˜7Kšžœžœžœžœ˜Kšœ8žœ ˜FKšžœ˜—K˜š œ$˜3KšœFžœ˜MK˜—K˜K˜4K˜4K˜Kšžœ˜—…—I,o