DIRECTORY Atom, BasicTime USING [GMT, Period, ToNSTime], CommandTool 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], PBasics USING [IsBound], RefTab, Rope, SimpleFeedback, UserProfile USING [CallWhenProfileChanges, ProfileChangedProc, Boolean]; MimosaAndCinderDeps: CEDAR MONITOR IMPORTS Atom, BasicTime, CommandTool, FS, IO, MakeDo, MakeDoParsers, MakeDoPrivate, MakeDoPorting, Mobery, MobListerUtils, PBasics, 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 ~ CommandTool.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 _ " -lc "; cTail: ROPE = ".c2c.c"; cTailLength: CARDINAL = cTail.Length[]; mobExt: ROPE = "mob"; mobTail: ROPE = Rope.Cat[".", 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 _ baseName.Cat[mobTail], fileClass]; cNode _ GetNode[cName _ baseName.Concat[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[mobName.Cat[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 _ PBasics.IsBound[LOOPHOLE[Mobery.StampAndNameFromFile]]; moblisteries _ PBasics.IsBound[LOOPHOLE[MobListerUtils.PrintVersion]] AND PBasics.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.PutF[ " 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.PutF[ " 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.PutFR["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.PutFR["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[name.Cat[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]; SELECT md.resultType FROM Unknown, MobAndC => NULL; MobOnly => cmd _ Rope.Cat[cmd, "; Delete ", md.shortName, cTail]; ENDCASE => ERROR; }; 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.PutF[myRouterName, oneLiner, $Log, fmt, 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 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 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... 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 – "cedar" style™code™K™Kšœœ ˜Kšœ˜Kšœ˜Kšœ˜Kšœ œ7˜H—K˜šΡbnxœœ˜"Kšœœœƒ˜―š ™ 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Οe™F—Kšœ&œ˜*Kšœœœ˜%Kšœœœ˜Kšœœ˜K˜—K˜Kšœ œ&˜6Kšœ œ'˜7K˜š œ œœœœ˜;K˜ šœ˜KšœK™K——K˜Kšœ œ)˜9Kšœœœ˜$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šœ>˜>Kšœ;˜;šœœ˜'Kšœ˜K˜ Kšœ˜Kšœ˜Kšœ8˜8Kšœ:˜:Kšœ<˜K˜%Kšœ0œ˜>Kšœœ˜"K˜—Kšœ˜—šœ˜K™Kšœ8œœœ$˜pK˜——Kšœ˜—šœ&œ˜.Kšœœ˜Kš œ8œœœœJ˜šKšœ˜—Kšœ œ˜Kšœ$˜$Kšœ%˜%Kš œœœœœ˜:Kš œœœœœœD˜nKšœ˜—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šœ œœ)˜;K˜)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šœ˜Kšœœ˜KšœA˜AKšœœ˜—Kšœ˜—šœ ˜ Kšœ#€œ˜8Kšœ5˜5Kšœ˜—Kšœœ˜Kšœœ˜!—K˜ Kšœ˜—K˜š Ÿœœ5œ œœ œ'˜¦Kš œ£ œ£œ £ œ6£ œ£ œ™ΆK˜?Kš œœœœœ ˜'K˜:Kšœœ˜—K˜šŸœœœ œ˜7Kšœœœœ˜K˜?Kšœ˜—K˜šŸœ$˜3KšœFœ˜MK˜—K˜K˜4K˜4K˜Kšœ˜—…—In;