<<>> <> <> <> <> <> <> <> <> <> <> DIRECTORY Basics USING[Comparison], BasicTime USING[earliestGMT, GMT, Now, Period], CirioNubAccess USING[CreateRemoteNub, DestroyNub, Handle], Commander USING[CommandProc, Register], CommanderOps USING[NextArgument, NumArgs], CommandTool USING[ArgumentVector, Parse], Convert USING[CardFromRope, Error], ObjectFiles USING[BracketNest, BracketPair, CreateParsed, FileSegmentPC, FindVersionStamp, GetBracketNestForPC, GetLineNumForPC, GetModuleInfo, GetObjectFile, GetPCForLineNum, GetPCRange, Module, ModuleFromParsedAndPC, ModuleInfo, Parsed, PCRange, VersionStampInfo], IO USING[card, EndOf, GetLine, PutF, PutFLR, PutFR, rope, STREAM], List USING[Sort], LoadStateAccess USING[BasicPCInfo, CreateLoadStateHandle, GetBasicPCInfo, GetLoadedModuleInfoFromAbsPC, GetLoadedModuleInfoFromStemName, GetRopeForBasicPCInfo, GetRopeListForBasicPCInfo, GetRopeListForLoadedModuleInfo, LoadedModuleInfo, LoadStateHandle], MobAccess USING[ComputeSourceVersionStamp, CreateMobCookie, MobCookie, MobError, ReadMobVersionStamp, ReadSourceVersionStamp], MobDefs USING[NullVersion, VersionStamp], MobObjectFiles USING[CreateJointMobParsedInfo, JointMobParsedInfo], MorePfsNames, NewRMTW USING[CedarBreakAddress, CedarSourcePosition, LoadedModuleInfo], PFS, PFSNames, RMTWBackdoor, RMTWPrivate USING [NameParts], PBasics USING[BITXOR, LongNumber], RefTab USING[Create, Fetch, Key, Ref, Store], Rope, RopeParts, RuntimeError USING[BoundsFault], SourceFileOpsExtras, SystemInterface USING[CirioFile, CirioFileInfo, CloseFileSet, CreateFileSet, FileSet, GenCirioFilesForInfo, GenVersionMapFilesForInfo, GetCirioFile, GetFileInfo, GetNameOfFile, GetStreamForFile, ReleaseStreamForFile, ShowReport, VersionStampToUniqueID], UserProfile USING [Token]; <> <> <> <<>> <> <<>> <> <<>> <> <<>> <<>> < dotO working. New implementation recognizes source version stamps, and I am editing in GetMesa. Must repair getMob to either check source version stamp, or mob versoin stamp, depending on which is present.>> <<>> <> RMTWModules: CEDAR MONITOR LOCKS modules USING modules: CedarModuleSet IMPORTS BasicTime, CirioNubAccess, Commander, CommanderOps, CommandTool, Convert, IO, List, LoadStateAccess, MobAccess, MobObjectFiles, MorePfsNames, ObjectFiles, PBasics, PFS, PFSNames, RefTab, Rope, RopeParts, RuntimeError, SourceFileOpsExtras, SystemInterface, UserProfile EXPORTS NewRMTW, RMTWBackdoor, RMTWPrivate = BEGIN OPEN LSA:LoadStateAccess, ObjF:ObjectFiles, MA:MobAccess, MOF:MobObjectFiles, MPfsN:MorePfsNames, RMTWPrivate; ROPE: TYPE ~ Rope.ROPE; PATH: TYPE ~ PFSNames.PATH; CirioFile: TYPE = SystemInterface.CirioFile; CedarModuleSet: TYPE = REF CedarModuleSetBody; CedarModuleSetBody: PUBLIC TYPE = MONITORED RECORD[ fileSet: SystemInterface.FileSet, searchPaths: LIST OF PATH, otherDirectories: LIST OF PATH, remoteServer: Rope.ROPE, table: RefTab.Ref, loadedTable: RefTab.Ref, flushTime: BasicTime.GMT, vsHash: VSHashTable, defMobs: VSHashTable]; <> <> CedarModule: TYPE = REF CedarModuleHandle; CedarModuleHandle: TYPE = REF CedarModuleBody; CedarModuleBody: TYPE = RECORD[ moduleSet: CedarModuleSet, mobStamp: REF MobDefs.VersionStamp, sourceStamp: REF MobDefs.VersionStamp, possiblePrincipalDirectories: LIST OF PATH, originalPossibleNameStems: LIST OF PATH, possibleNameStems: LIST OF PATH, failureTime: BasicTime.GMT, mesaSourceFailed: BOOLEAN, mobFileFailed: BOOLEAN, mobFailed: BOOLEAN, cSourceFailed: BOOLEAN, jmpiFailed: BOOLEAN, moduleFailed: BOOLEAN, wholeFailed: BOOLEAN, loadedJmpiFailed: BOOLEAN, mesaSource: CirioFile, jmpi: MOF.JointMobParsedInfo, mobFile: CirioFile, mob: MA.MobCookie, cInfo: CFileInfo, module: ObjF.Module, whole: ObjF.Parsed, loadedJmpi: MOF.JointMobParsedInfo, loadedModule: ObjF.Module, loadedWhole: ObjF.Parsed, loadedModuleInfo: REF LoadStateAccess.LoadedModuleInfo]; <> CreateCedarModuleSet: PUBLIC PROC[fileSet: SystemInterface.FileSet, remoteServer: Rope.ROPE _ NIL] RETURNS[CedarModuleSet] = BEGIN table: RefTab.Ref _ RefTab.Create[]; loadedTable: RefTab.Ref _ RefTab.Create[]; vsHash: VSHashTable _ CreateVSHashTable[]; defMobs: VSHashTable _ CreateVSHashTable[]; RETURN[NEW[CedarModuleSetBody_[ , fileSet, NIL, NIL, remoteServer, table, loadedTable, BasicTime.Now[], vsHash, defMobs]]]; END; ResetSearchPaths: PUBLIC ENTRY PROC[modules: CedarModuleSet, searchPaths: LIST OF PATH, flushTime: BasicTime.GMT] = BEGIN ENABLE UNWIND => NULL; modules.searchPaths _ searchPaths; modules.flushTime _ flushTime; END; FlushUnknownFileCache: PUBLIC ENTRY PROC[modules: CedarModuleSet, flushTime: BasicTime.GMT] = BEGIN ENABLE UNWIND => NULL; modules.flushTime _ flushTime; END; CedarSourcePosition: TYPE = NewRMTW.CedarSourcePosition; GetCedarSourcePosition: PUBLIC ENTRY PROC[modules: CedarModuleSet, loadedModule: REF LoadStateAccess.LoadedModuleInfo, absPC: CARD] RETURNS[REF CedarSourcePosition] ~ { ENABLE UNWIND => NULL; module: CedarModule ~ GetCedarModuleForLoadedModule[modules, loadedModule]; moduleRelativePC: CARD ~ IF loadedModule # NIL THEN absPC - (loadedModule.lsi[text].base + loadedModule.moduleRelativeBaseAddr) ELSE 0; RETURN[ComputeCedarSourcePosition[module, [[0, ""], moduleRelativePC]]]}; ComputeCedarSourcePosition: PROC[module: CedarModule, spc: ObjF.FileSegmentPC] RETURNS[REF CedarSourcePosition] = BEGIN IF module = NIL THEN RETURN[NEW[CedarSourcePosition_[spc.relPC, NIL, 0, NIL, 0, "unknown mesa module"]]] ELSE BEGIN embeddedModule: ObjF.Module _ GetModule[module]; moduleInfo: REF ObjF.ModuleInfo _ IF embeddedModule # NIL THEN ObjF.GetModuleInfo[embeddedModule] ELSE NIL; parsedRelativePC: ObjF.FileSegmentPC _ [[0, ""], IF moduleInfo # NIL THEN 0--pj moduleInfo.startPC--+spc.relPC ELSE 0]; cLine: CARD _ IF moduleInfo # NIL THEN ObjF.GetLineNumForPC[embeddedModule, parsedRelativePC] ELSE 0; cInfo: CFileInfo _ GetCFileInfo[module]; cFile: CirioFile _ IF cInfo # NIL THEN cInfo.file ELSE NIL; mesaPosition: CARD _ IF cInfo # NIL THEN LookupCLineNum[cInfo, cLine] ELSE 0; remarks: Rope.ROPE _ NIL; IF embeddedModule # NIL AND cInfo # NIL THEN -- check back with parsed BEGIN correspondingcLine: CARD _ LookupMesaSourcePos[cInfo, mesaPosition]; correspondingPC: ObjF.FileSegmentPC _ ObjF.GetPCForLineNum[embeddedModule, correspondingcLine]; originalNest: ObjF.BracketNest _ ObjF.GetBracketNestForPC[embeddedModule, correspondingPC]; originalPair: ObjF.BracketPair _ IF originalNest = NIL THEN NIL ELSE originalNest.rest.first; pcRange: ObjF.PCRange _ IF originalPair = NIL THEN [0, 0] ELSE ObjF.GetPCRange[originalPair]; IF originalPair = NIL OR correspondingPC.relPC < pcRange.first OR pcRange.limit <= correspondingPC.relPC THEN remarks _ IO.PutFR["Source location is potentially erroneous (because it corresponds to c line number %g as well as %g, and the two are in distinct C blocks).", [cardinal[correspondingcLine]], [cardinal[cLine]]]; END; RETURN[NEW[CedarSourcePosition_[spc.relPC, GetMesaFile[module], mesaPosition, cFile, cLine, remarks]]]; END END; <<>> <> GetRopesForSourcePosInfo: PUBLIC PROC[info: REF CedarSourcePosition] RETURNS[LIST OF Rope.ROPE] = BEGIN ropes: LIST OF Rope.ROPE _ NIL; mesaName: PATH _ IF info.mesa = NIL THEN PFSNames.EmptyPath ELSE SystemInterface.GetNameOfFile[info.mesa]; cName: PATH _ IF info.cFile = NIL THEN PFSNames.EmptyPath ELSE SystemInterface.GetNameOfFile[info.cFile]; IF info.remarks # NIL THEN ropes _ CONS[info.remarks, ropes]; ropes _ CONS[IO.PutFR[" line in %g is %g", IO.rope[PFS.RopeFromPath[cName]], IO.card[info.cLineNum]], ropes]; IF info.mesaPosition # 0 THEN ropes _ CONS[IO.PutFR[" position in %g is %g", IO.rope[PFS.RopeFromPath[mesaName]], IO.card[info.mesaPosition]], ropes]; IF info.mesaPosition = 0 THEN ropes _ CONS[IO.PutFR[" position is somewhere in %g", IO.rope[PFS.RopeFromPath[mesaName]]], ropes]; ropes _ CONS[IO.PutFR["for relative pc: %g", IO.card[info.relativePC]], ropes]; RETURN[ropes] END; LoadedModuleInfo: TYPE = NewRMTW.LoadedModuleInfo; LoadedModule: TYPE = REF LoadedModuleBody; LoadedModuleBody: TYPE = RECORD[ module: CedarModule, loadedModule: REF LoadStateAccess.LoadedModuleInfo, loadedModuleFailedTime: BasicTime.GMT]; GetLoadedModuleInfo: PUBLIC ENTRY PROC[modules: CedarModuleSet, loadedModule: REF LoadStateAccess.LoadedModuleInfo] RETURNS[REF LoadedModuleInfo] = BEGIN ENABLE UNWIND => NULL; module: CedarModule _ GetCedarModuleForLoadedModule[modules, loadedModule]; IF module = NIL THEN RETURN[NIL] ELSE RETURN[NEW[LoadedModuleInfo_[ jmpi: GetLoadedJMPI[module], mob: GetMob[module], loadedModule: loadedModule]]]; END; CedarBreakAddress: TYPE = NewRMTW.CedarBreakAddress; <> GetAbsAddressForBreak: PUBLIC ENTRY PROC[modules: CedarModuleSet, mesa: CirioFile, loadState: LoadStateAccess.LoadStateHandle, sourcePos: CARD] RETURNS[REF CedarBreakAddress] = BEGIN ENABLE UNWIND => NULL; lm: LoadedModule _ GetLoadedModuleForMesa[modules, mesa, loadState]; IF lm = NIL OR lm.module = NIL OR lm.loadedModule = NIL THEN RETURN[NIL] ELSE BEGIN cInfo: CFileInfo _ GetCFileInfo[lm.module]; IF cInfo = NIL THEN RETURN[NIL] ELSE BEGIN cLineNum: CARD _ LookupMesaSourcePos[cInfo, sourcePos]; parsedRelativePC: ObjF.FileSegmentPC _ ObjF.GetPCForLineNum[lm.loadedModule.module, cLineNum]; correspondingCLineNum: CARD _ ObjF.GetLineNumForPC[lm.loadedModule.module, parsedRelativePC]; correspondingMesaPos: CARD _ LookupCLineNum[cInfo, correspondingCLineNum]; moduleRelPC: CARD _ parsedRelativePC.relPC - lm.loadedModule.moduleRelativeBaseAddr; absPC: CARD _ lm.loadedModule.lsi[text].base+parsedRelativePC.relPC; RETURN[NEW[CedarBreakAddress_[mesa, sourcePos, cInfo.file, cLineNum, [[0, ""], moduleRelPC], correspondingCLineNum, correspondingMesaPos, lm.loadedModule, absPC]]]; END; END END; <> GetRopesForCedarBreakAddress: PUBLIC PROC[addr: REF CedarBreakAddress] RETURNS[LIST OF Rope.ROPE] = BEGIN IF addr = NIL THEN RETURN[LIST["failed to set break"]] ELSE BEGIN mesa: PATH _ SystemInterface.GetNameOfFile[addr.mesa]; cname: PATH _ SystemInterface.GetNameOfFile[addr.cFile]; rope1: Rope.ROPE _ IO.PutFR["setting break in %g at source pos = %g", IO.rope[PFS.RopeFromPath[mesa]], IO.card[addr.mesaPosition]]; rope2: Rope.ROPE _ IO.PutFR[" C line num = %g in %g", IO.card[addr.cLineNum], IO.rope[PFS.RopeFromPath[cname]]]; rope3: Rope.ROPE _ IO.PutFR[" module relative pos = %g", IO.card[addr.moduleRelativePC.relPC]]; rope4: Rope.ROPE _ IO.PutFR[" corresponding C line num = %g", IO.card[addr.correspondingCLineNum]]; rope5: Rope.ROPE _ IO.PutFR[" resulting mesa source pos = %g", IO.card[addr.correspondingMesaPosition]]; rope6: Rope.ROPE _ IO.PutFR[" abs pos = %g", IO.card[addr.absPC]]; RETURN[LIST[rope1, rope2, rope3, rope4, rope5, rope6]]; END; END; DefMobHolder: TYPE = RECORD[failureTime: BasicTime.GMT, mob: MA.MobCookie]; <> <> GetDefinitionMob: PUBLIC ENTRY PROC[modules: CedarModuleSet, vs: MobDefs.VersionStamp, stem: PATH _ NIL] RETURNS[MA.MobCookie] = BEGIN ENABLE UNWIND => NULL; vsKey: RefTab.Key _ CreateVSKey[vs, emptyRopePart]; mobRef: REF DefMobHolder _ NARROW[RefTab.Fetch[modules.defMobs.table, vsKey].val]; IF mobRef = NIL THEN BEGIN mobRef _ NEW[DefMobHolder_[modules.flushTime, NIL]]; IF NOT RefTab.Store[modules.defMobs.table, vsKey, mobRef] THEN ERROR; END; IF mobRef.mob = NIL AND BasicTime.Period[mobRef.failureTime, modules.flushTime] >= 0 THEN BEGIN foundMob: MA.MobCookie _ NIL; -- tentative foundPossibleFile: CirioFile _ NIL; -- tentative foundCreateTime: BasicTime.GMT _ BasicTime.earliestGMT; -- tentative AcceptOneFile: PROC [info: SystemInterface.CirioFileInfo] RETURNS[thisIsIt: BOOLEAN _ FALSE] = { possibleFile: CirioFile; mob: MA.MobCookie; mobStamp: MobDefs.VersionStamp; possibleFile _ SystemInterface.GetCirioFile[modules.fileSet, info.fullName, info.uniqueID]; mob _ MA.CreateMobCookie[possibleFile ! MobAccess.MobError => { SystemInterface.ShowReport[IO.PutFR["\tbad mob %g", [rope[PFS.RopeFromPath[info.fullName]]] ], IF debugSearch THEN $urgent ELSE $debug]; GOTO failure}]; mobStamp _ MA.ReadMobVersionStamp[mob]; IF debugSearch THEN SystemInterface.ShowReport[IO.PutFR["\t?name=%g,\n\tmobStamp=%08x%08x.", [rope[PFS.RopeFromPath[info.fullName]]], [cardinal[mobStamp[0]]], [cardinal[mobStamp[1]]] ], $urgent]; foundMob _ mob; foundPossibleFile _ possibleFile; foundCreateTime _ info.uniqueID.egmt.time; RETURN[TRUE]; EXITS failure => RETURN [FALSE]}; TryOneFile: PROC[info: SystemInterface.CirioFileInfo] RETURNS[thisIsIt: BOOLEAN _ FALSE] = { possibleFile: CirioFile; mob: MA.MobCookie; mobStamp: MobDefs.VersionStamp; possibleFile _ SystemInterface.GetCirioFile[modules.fileSet, info.fullName, info.uniqueID]; mob _ MA.CreateMobCookie[possibleFile ! MobAccess.MobError => { SystemInterface.ShowReport[IO.PutFR["\tbad mob %g", [rope[PFS.RopeFromPath[info.fullName]]] ], IF debugSearch THEN $urgent ELSE $debug]; GOTO failure}]; mobStamp _ MA.ReadMobVersionStamp[mob]; IF debugSearch THEN SystemInterface.ShowReport[IO.PutFR["\t?name=%g,\n\tmobStamp=%08x%08x.", [rope[PFS.RopeFromPath[info.fullName]]], [cardinal[mobStamp[0]]], [cardinal[mobStamp[1]]] ], $urgent]; IF vs = mobStamp THEN { foundMob _ mob; foundPossibleFile _ possibleFile; foundCreateTime _ info.uniqueID.egmt.time; RETURN[TRUE]}; RETURN[FALSE]; EXITS failure => RETURN [FALSE]}; TryOneDir: PROC[dir: PATH] = BEGIN <> mobFileNamePattern: PATH _ PFS.PathFromRope[Rope.Cat[PFS.RopeFromPath[stem], ".mob", "*"]].ExpandName[dir]; IF debugSearch THEN SystemInterface.ShowReport[IO.PutFR["\tSearching file pattern %g.", [rope[PFS.RopeFromPath[mobFileNamePattern]]] ], $urgent]; [] _ SystemInterface.GenCirioFilesForInfo[modules.fileSet, mobFileNamePattern, TryOneFile]; END; SystemInterface.ShowReport[Rope.Cat["searching for mob for ", IF stem#NIL THEN PFS.RopeFromPath[stem] ELSE "???"], $normal]; IF stem=NIL THEN SystemInterface.ShowReport[IO.PutFR["\twith mobStamp=%08x%08x.", [cardinal[vs[0]]], [cardinal[vs[1]]] ], IF debugSearch THEN $urgent ELSE $normal]; IF stem#NIL THEN FOR dirs: LIST OF PATH _ modules.searchPaths, dirs.rest WHILE dirs # NIL AND foundPossibleFile = NIL DO IF debugSearch THEN SystemInterface.ShowReport[IO.PutFR["\tSearching search dir %g.", [rope[PFS.RopeFromPath[dirs.first]]] ], $urgent]; TryOneDir[dirs.first]; ENDLOOP; IF foundPossibleFile = NIL THEN { IF debugSearch THEN SystemInterface.ShowReport["\tSearching version maps.", $urgent]; IF stem#NIL THEN foundPossibleFile _ SystemInterface.GenVersionMapFilesForInfo[modules.fileSet, $Intermediate, vs, LIST[stem], LIST[".mob"], TRUE, AcceptOneFile] ELSE foundPossibleFile _ SystemInterface.GenVersionMapFilesForInfo[modules.fileSet, $Intermediate, vs, LIST[MPfsN.Cons1[MPfsN.ConstructComponent[["*"], [none]]]], LIST[".mob"], TRUE, AcceptOneFile]; }; IF stem#NIL THEN FOR dirs: LIST OF PATH _ modules.otherDirectories, dirs.rest WHILE dirs # NIL AND foundPossibleFile = NIL DO IF debugSearch THEN SystemInterface.ShowReport[IO.PutFR["\tSearching other dir %g.", [rope[PFS.RopeFromPath[dirs.first]]] ], $urgent]; TryOneDir[dirs.first]; ENDLOOP; IF foundPossibleFile = NIL THEN BEGIN mobRef.failureTime _ BasicTime.Now[]; SystemInterface.ShowReport[Rope.Cat["unable to find mob for ", IF stem#NIL THEN PFS.RopeFromPath[stem] ELSE "???"], $urgent]; END ELSE BEGIN mobName: PATH _ SystemInterface.GetNameOfFile[foundPossibleFile]; <> mobRef.mob _ foundMob; SystemInterface.ShowReport[Rope.Cat[" found ", PFS.RopeFromPath[mobName]], $normal]; END; END; RETURN[mobRef.mob]; END; <> <<>> GetLoadedModuleForMesa: PROC[modules: CedarModuleSet, mesa: CirioFile, loadState: LoadStateAccess.LoadStateHandle] RETURNS[LoadedModule] = BEGIN lm: LoadedModule _ NARROW[RefTab.Fetch[modules.loadedTable, mesa].val]; IF lm = NIL THEN BEGIN lm _ NEW[LoadedModuleBody_[NIL, NIL, modules.flushTime]]; IF NOT RefTab.Store[modules.loadedTable, mesa, lm] THEN ERROR; END; IF lm.loadedModule = NIL AND (BasicTime.Period[lm.loadedModuleFailedTime, modules.flushTime] >= 0) THEN BEGIN mesaName: PATH _ SystemInterface.GetNameOfFile[mesa]; givenSourceStamp: MobDefs.VersionStamp _ MA.ComputeSourceVersionStamp[mesa]; parts: NameParts _ GetNamePartsFromFullPathName[mesaName]; stemRope: Rope.ROPE _ parts.nameStem; module: CedarModule _ NIL; lm.loadedModuleFailedTime _ BasicTime.Now[]; -- if needed SystemInterface.ShowReport[IO.PutFR["Searching for loaded module %g created at %g (source stamp=%g).", [rope[stemRope]], [time[SystemInterface.GetFileInfo[mesa].uniqueID.egmt.time]], [rope[FmtStamp[givenSourceStamp]]] ], $normal]; IF parts.principalDirectory # PFSNames.EmptyPath THEN modules.otherDirectories _ AddAName[parts.principalDirectory, modules.otherDirectories]; FOR skip: CARD _ 1--despite comment under CirioNubAccess.LookupMatchingSymEntryByName, which is inconsistent with the general pattern, 0 and 1 find the same thing(MJS thinks at June 8, 1991)--, skip+1 DO loadedModule: REF LoadStateAccess.LoadedModuleInfo _ LoadStateAccess.GetLoadedModuleInfoFromStemName[loadState, parts.nameStem, skip, modules]; IF loadedModule=NIL THEN { SystemInterface.ShowReport[IO.PutFR["Giving up search for loaded module %g at skip=%g.", [rope[stemRope]], [cardinal[skip]] ], $normal]; EXIT}; module _ GetCedarModuleForLoadedModule[modules, loadedModule]; IF module#NIL THEN { ldoPath: PATH ~ loadedModule.loadedFile.GetNameOfFile[]; ldoRope: Rope.ROPE ~ PFS.RopeFromPath[ldoPath]; [] _ GetMob[module]; IF module.sourceStamp=NIL THEN SystemInterface.ShowReport[IO.PutFR["Rejecting the one in %g of %g (found at skip=%g) for lack of source version stamp.", [rope[ldoRope]], [time[loadedModule.createTimeOfLoadedFile]], [cardinal[skip]] ], $normal] ELSE IF module.sourceStamp^ = givenSourceStamp THEN { lm.module _ module; lm.loadedModule _ loadedModule; SystemInterface.ShowReport[IO.PutFR["Accepting the one in %g of %g (found at skip=%g).", [rope[ldoRope]], [time[loadedModule.createTimeOfLoadedFile]], [cardinal[skip]] ], $normal]; RETURN [lm]} ELSE SystemInterface.ShowReport[IO.PutFR["Rejecting the one in %g of %g (found at skip=%g) because source version stamp (%g) isn't right.", [rope[ldoRope]], [time[loadedModule.createTimeOfLoadedFile]], [cardinal[skip]], [rope[FmtStamp[module.sourceStamp^]]] ], $normal] }; ENDLOOP; END; RETURN[lm]; END; FmtStamp: PROC [stamp: MobDefs.VersionStamp] RETURNS [Rope.ROPE] ~ {RETURN IO.PutFR["%08x%08x", [cardinal[stamp[0]]], [cardinal[stamp[1]]] ]}; GetCedarModuleForLoadedModule: PROC[modules: CedarModuleSet, info: REF LoadStateAccess.LoadedModuleInfo] RETURNS[CedarModule] = BEGIN IF info = NIL THEN RETURN[NIL] ELSE BEGIN tentative: CedarModule _ CreateCedarModuleFromModule[modules, info.parsed, info.module, info.possibleModuleFileNames]; IF tentative#NIL AND tentative.loadedModuleInfo=NIL THEN tentative.loadedModuleInfo _ info; RETURN[tentative]; END END; <> CreateCedarModuleFromMesa: PROC[modules: CedarModuleSet, mesa: CirioFile] RETURNS[CedarModule] = BEGIN sourceStamp: REF MobDefs.VersionStamp _ NEW[MobDefs.VersionStamp_MA.ComputeSourceVersionStamp[mesa]]; mesaName: PATH _ SystemInterface.GetNameOfFile[mesa]; parts: NameParts _ GetNamePartsFromFullPathName[mesaName]; <> base: RopeParts.RopePart _ RopeParts.InlineMake[parts.nameStem]; vsKey: RefTab.Key _ CreateVSKey[sourceStamp^, base]; module: CedarModule _ NARROW[RefTab.Fetch[modules.vsHash.table, vsKey].val]; IF module = NIL THEN BEGIN <> <> module _ CreateEmptyCedarModule[modules]; module.possiblePrincipalDirectories _ LIST[parts.principalDirectory]; module.originalPossibleNameStems _ LIST[PFS.PathFromRope[parts.nameStem]]; module.possibleNameStems _ module.originalPossibleNameStems; module.mesaSource _ mesa; module.sourceStamp _ sourceStamp; IF NOT RefTab.Store[modules.vsHash.table, vsKey, module] THEN ERROR; END; RETURN[module]; END; CreateCedarModuleFromModule: PROC[modules: CedarModuleSet, whole: ObjF.Parsed, embeddedModule: ObjF.Module, possibleModuleFileNames: LIST OF PATH] RETURNS[CedarModule] = BEGIN vsInfo: REF ObjF.VersionStampInfo _ ObjF.FindVersionStamp[embeddedModule]; recoveredStamp: REF RecoveredVersionStamp _ IF vsInfo = NIL OR Rope.IsEmpty[vsInfo.contents] THEN NIL ELSE ConvertDotOFormatVersionStampToMobFormat[vsInfo.contents]; mobStamp: REF MobDefs.VersionStamp _ IF recoveredStamp = NIL THEN NIL ELSE NEW[MobDefs.VersionStamp_recoveredStamp.mobStamp]; vsKey: RefTab.Key _ IF mobStamp = NIL THEN NIL ELSE CreateVSKey[mobStamp^, emptyRopePart]; module: CedarModule _ IF mobStamp = NIL THEN NIL ELSE NARROW[RefTab.Fetch[modules.vsHash.table, vsKey].val]; IF module = NIL THEN BEGIN moduleInfo: REF ObjF.ModuleInfo _ ObjF.GetModuleInfo[embeddedModule]; -- for SunOS5.x IF mobStamp = NIL THEN RETURN[NIL]; module _ CreateEmptyCedarModule[modules]; module.module _ embeddedModule; module.whole _ whole; module.mobStamp _ mobStamp; IF whole = moduleInfo.whole THEN -- normal case BEGIN FOR names: LIST OF PATH _ possibleModuleFileNames, names.rest WHILE names # NIL DO parts: NameParts _ GetNamePartsFromFullPathName[names.first]; IF parts.nameStem.Length[] # 0 THEN module.originalPossibleNameStems _ AddAName[PFS.PathFromRope[parts.nameStem], module.originalPossibleNameStems]; IF parts.principalDirectory # PFSNames.EmptyPath THEN module.possiblePrincipalDirectories _ AddAName[parts.principalDirectory, module.possiblePrincipalDirectories]; ENDLOOP; <> BEGIN wholeFileName: PATH _ SystemInterface.GetNameOfFile[ObjF.GetObjectFile[whole]]; parts: NameParts _ GetNamePartsFromFullPathName[wholeFileName]; IF parts.principalDirectory # PFSNames.EmptyPath THEN BEGIN modules.otherDirectories _ AddAName[parts.principalDirectory, modules.otherDirectories]; modules.flushTime _ BasicTime.Now[]; END; END; END ELSE -- SunOS 5.x - couldn't obtain debug information from loaded object module BEGIN parts: NameParts _ GetNamePartsFromFullPathName[moduleInfo.fileName]; IF parts.nameStem.Length[] # 0 THEN module.originalPossibleNameStems _ AddAName[PFS.PathFromRope[parts.nameStem], module.originalPossibleNameStems]; IF parts.principalDirectory # PFSNames.EmptyPath THEN module.possiblePrincipalDirectories _ AddAName[parts.principalDirectory, module.possiblePrincipalDirectories]; <> BEGIN wholeFileName: PATH _ SystemInterface.GetNameOfFile[ObjF.GetObjectFile[moduleInfo.whole]]; parts: NameParts _ GetNamePartsFromFullPathName[wholeFileName]; IF parts.principalDirectory # PFSNames.EmptyPath THEN BEGIN modules.otherDirectories _ AddAName[parts.principalDirectory, modules.otherDirectories]; modules.flushTime _ BasicTime.Now[]; END; END; END; IF NOT RefTab.Store[modules.vsHash.table, vsKey, module] THEN ERROR; END; IF module # NIL THEN -- just in case BEGIN IF module.module = NIL THEN module.module _ embeddedModule; IF module.whole = NIL THEN module.whole _ whole; END; RETURN[module]; END; CreateEmptyCedarModule: PROC[modules: CedarModuleSet] RETURNS[CedarModule] = {RETURN[NEW[CedarModuleHandle_NEW[CedarModuleBody_[modules, NIL, NIL, NIL, NIL, NIL, BasicTime.Now[], FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NIL, NIL, NIL, NIL, NIL, NIL, NIL]]]]}; <> GetLoadedJMPI: PROC[module: CedarModule] RETURNS[MOF.JointMobParsedInfo] = BEGIN IF module.loadedJmpi = NIL AND NOT (module.loadedJmpiFailed AND BasicTime.Period[module.failureTime, module.moduleSet.flushTime] < 0) THEN BEGIN mob: MA.MobCookie _ GetMob[module]; loadedModule: ObjF.Module _ GetLoadedModule[module]; loadedDotO: ObjF.Parsed _ GetLoadedParsed[module]; IF mob # NIL AND loadedModule # NIL AND loadedDotO # NIL THEN module.loadedJmpi _ MOF.CreateJointMobParsedInfo[mob, loadedDotO, loadedModule]; IF module.loadedJmpi = NIL THEN {module.loadedJmpiFailed _ TRUE; module.failureTime _ BasicTime.Now[]} END; RETURN[module.loadedJmpi]; END; GetLoadedParsed: PROC[module: CedarModule] RETURNS[ObjF.Parsed] = BEGIN IF module.loadedWhole = NIL AND module.loadedModuleInfo # NIL THEN module.loadedWhole _ module.loadedModuleInfo.parsed; RETURN[module.loadedWhole]; END; GetLoadedModule: PROC[module: CedarModule] RETURNS[ObjF.Module] = BEGIN IF module.loadedModule = NIL AND module.loadedModuleInfo # NIL THEN module.loadedModule _ module.loadedModuleInfo.module; RETURN[module.loadedModule]; END; <<>> <<>> <> SeekCSource: PUBLIC PROC [cms: CedarModuleSet, basicInfo: REF LSA.BasicPCInfo, ledo: REF LSA.LoadedModuleInfo] RETURNS [foundFile: SystemInterface.CirioFile _ NIL] ~ { TryOneFile: PROC[info: SystemInterface.CirioFileInfo] RETURNS[thisIsIt: BOOLEAN] = {RETURN[TRUE]}; TryOneDir: PROC[dir: PATH] = { IF debugSearch THEN SystemInterface.ShowReport[IO.PutFR["\tSearching directory %g.", [rope[PFS.RopeFromPath[dir]]] ], $urgent]; FOR spats: LIST OF ROPE _ pats, spats.rest WHILE spats#NIL AND foundFile=NIL DO mesaPathName: PATH _ PFS.PathFromRope[spats.first]; mesaPathNamePattern: PATH _ mesaPathName.ExpandName[dir]; foundFile _ SystemInterface.GenCirioFilesForInfo[cms.fileSet, mesaPathNamePattern, TryOneFile]; ENDLOOP; RETURN}; pats: LIST OF ROPE _ NIL; paths: LIST OF PATH _ NIL; descr: ROPE _ NIL; FOR pmns: LIST OF PATH _ basicInfo.possibleModuleNames, pmns.rest WHILE pmns#NIL DO short: ROPE _ PFS.RopeFromPath[pmns.first]; sl: INT _ short.Length; this: ROPE; IF sl>2 AND short.EqualSubstrs[start1: sl-2, s2: ".o"] THEN this _ short.Replace[sl-1, 1, "c"] ELSE this _ short.Concat[".c"]; IF descr=NIL THEN descr _ this ELSE descr _ Rope.Cat[descr, " or ", this]; pats _ CONS[this, pats]; paths _ CONS[PFS.PathFromRope[this], paths]; ENDLOOP; SystemInterface.ShowReport[Rope.Concat["Searching for C source in ", descr], $normal]; FOR dirs: LIST OF PATH _ cms.searchPaths, dirs.rest WHILE dirs # NIL AND foundFile = NIL DO TryOneDir[dirs.first]; ENDLOOP; IF foundFile = NIL THEN { IF debugSearch THEN SystemInterface.ShowReport["\tTrying version maps.", $urgent]; foundFile _ SystemInterface.GenVersionMapFilesForInfo[cms.fileSet, $Source, MobDefs.NullVersion, paths, LIST[""], TRUE, TryOneFile]}; FOR dirs: LIST OF PATH _ cms.otherDirectories, dirs.rest WHILE dirs # NIL AND foundFile = NIL DO TryOneDir[dirs.first]; ENDLOOP; IF foundFile # NIL THEN { nameRope: PATH _ SystemInterface.GetNameOfFile[foundFile]; SystemInterface.ShowReport[Rope.Cat[" found ", PFS.RopeFromPath[nameRope]], $normal]; } ELSE { SystemInterface.ShowReport[" failed", $normal]; }; RETURN}; GetMesaFile: PROC[module: CedarModule] RETURNS[CirioFile] = BEGIN IF module.mesaSource = NIL AND NOT (module.mesaSourceFailed AND BasicTime.Period[module.failureTime, module.moduleSet.flushTime] < 0) THEN BEGIN foundFile: CirioFile _ NIL; -- tentative mob: MA.MobCookie _ GetMob[module]; sourceUnique: PFS.UniqueID; <> TryOneFile: PROC[info: SystemInterface.CirioFileInfo] RETURNS[thisIsIt: BOOLEAN] = {RETURN[info.uniqueID = sourceUnique]}; TryOneDir: PROC[dir: PATH] = BEGIN FOR stems: LIST OF PATH _ module.possibleNameStems, stems.rest WHILE stems # NIL AND foundFile = NIL DO mesaPathName: PATH _ PFS.PathFromRope [Rope.Cat [PFS.RopeFromPath[stems.first], ".mesa*"]]; mesaPathNamePattern: PATH _ mesaPathName.ExpandName[dir]; foundFile _ SystemInterface.GenCirioFilesForInfo[module.moduleSet.fileSet, mesaPathNamePattern, TryOneFile]; ENDLOOP; END; IF module.sourceStamp#NIL THEN sourceUnique _ SystemInterface.VersionStampToUniqueID[module.sourceStamp^] ELSE IF mob#NIL THEN sourceUnique _ SystemInterface.VersionStampToUniqueID[MA.ReadSourceVersionStamp[mob]] ELSE RETURN[NIL]; ShowSearchReport["mesa source", module]; FOR dirs: LIST OF PATH _ module.moduleSet.searchPaths, dirs.rest WHILE dirs # NIL AND foundFile = NIL DO TryOneDir[dirs.first]; ENDLOOP; IF foundFile = NIL THEN foundFile _ SystemInterface.GenVersionMapFilesForInfo[module.moduleSet.fileSet, $Source, MobDefs.NullVersion, module.possibleNameStems, LIST[".mesa"], TRUE, TryOneFile, sourceUnique]; FOR dirs: LIST OF PATH _ module.possiblePrincipalDirectories, dirs.rest WHILE dirs # NIL AND foundFile = NIL DO TryOneDir[dirs.first]; ENDLOOP; FOR dirs: LIST OF PATH _ module.moduleSet.otherDirectories, dirs.rest WHILE dirs # NIL AND foundFile = NIL DO TryOneDir[dirs.first]; ENDLOOP; IF foundFile # NIL THEN BEGIN mesaName: PATH _ SystemInterface.GetNameOfFile[foundFile]; parts: NameParts _ GetNamePartsFromFullPathName[mesaName]; module.possiblePrincipalDirectories _ AddAName[parts.principalDirectory, module.possiblePrincipalDirectories]; module.possibleNameStems _ LIST[PFS.PathFromRope[parts.nameStem]]; module.mesaSource _ foundFile; module.mesaSourceFailed _ FALSE; SystemInterface.ShowReport[Rope.Cat[" found ", PFS.RopeFromPath[mesaName]], $normal]; END ELSE BEGIN module.mesaSourceFailed _ TRUE; module.failureTime _ BasicTime.Now[]; ShowFailureReport["mesa source", module]; END; END; RETURN[module.mesaSource]; END; GetCFileInfo: PROC[module: CedarModule] RETURNS[CFileInfo] = BEGIN IF module.cInfo = NIL AND NOT (module.cSourceFailed AND BasicTime.Period[module.failureTime, module.moduleSet.flushTime] < 0) THEN BEGIN [] _ GetMob[module]; -- always get the mob first. Thus, if we have a mesa source, then the corresponding mob will give us the mob version IF module.possibleNameStems # NIL THEN BEGIN foundFile: CirioFile _ NIL; -- tentative foundCInfo: CFileInfo _ NIL; -- tentative foundPossibleFile: CirioFile _ NIL; -- tentative <> TryOneFile: PROC[info: SystemInterface.CirioFileInfo] RETURNS[thisIsIt: BOOLEAN _ FALSE] = BEGIN IF module.mobStamp = NIL THEN <> BEGIN possibleFile: CirioFile _ SystemInterface.GetCirioFile[module.moduleSet.fileSet, info.fullName, info.uniqueID]; cInfo: CFileInfo _ CreateCFileInfo[possibleFile]; foundCInfo _ cInfo; foundPossibleFile _ possibleFile; SystemInterface.ShowReport[Rope.Cat["accepting ", PFS.RopeFromPath[info.fullName], " without checking version stamp"], $normal]; RETURN[TRUE] END ELSE BEGIN possibleFile: CirioFile _ SystemInterface.GetCirioFile[module.moduleSet.fileSet, info.fullName, info.uniqueID]; vsRope: Rope.ROPE _ ScanCFileForVersionStamp[possibleFile]; IF vsRope # NIL THEN BEGIN <> recoveredStamp: REF RecoveredVersionStamp _ ConvertDotOFormatVersionStampToMobFormat[vsRope]; IF recoveredStamp # NIL AND module.mobStamp # NIL AND module.mobStamp^ = recoveredStamp.mobStamp THEN BEGIN foundCInfo _ CreateCFileInfo[possibleFile]; foundPossibleFile _ possibleFile; RETURN[TRUE] END END; RETURN[FALSE]; END; END; TryOneDir: PROC[dir: PATH] = BEGIN FOR stems: LIST OF PATH _ module.possibleNameStems, stems.rest WHILE stems # NIL AND foundFile = NIL DO cFileNamePattern1: PATH _ PFS.PathFromRope[Rope.Cat[PFS.RopeFromPath[stems.first], ".c2c.c", "*"]]; cFileNamePattern2: PATH _ PFS.PathFromRope[Rope.Cat[PFS.RopeFromPath[stems.first], ".c", "*"]]; -- perhaps the conventions aren't being followed cFileNamePattern1 _ cFileNamePattern1.ExpandName[dir]; cFileNamePattern1 _ cFileNamePattern2.ExpandName[dir]; foundFile _ SystemInterface.GenCirioFilesForInfo[module.moduleSet.fileSet, cFileNamePattern1, TryOneFile]; IF foundFile = NIL THEN foundFile _ SystemInterface.GenCirioFilesForInfo[module.moduleSet.fileSet, cFileNamePattern2, TryOneFile] ENDLOOP; END; ShowSearchReport["c source", module]; FOR dirs: LIST OF PATH _ module.moduleSet.searchPaths, dirs.rest WHILE dirs # NIL AND foundFile = NIL DO TryOneDir[dirs.first]; ENDLOOP; IF foundFile = NIL THEN foundFile _ SystemInterface.GenVersionMapFilesForInfo[module.moduleSet.fileSet, $Intermediate, MobDefs.NullVersion, module.possibleNameStems, LIST[".c2c.c"], TRUE, TryOneFile]; IF foundFile = NIL THEN foundFile _ SystemInterface.GenVersionMapFilesForInfo[module.moduleSet.fileSet, $Source, MobDefs.NullVersion, module.possibleNameStems, LIST[".c"], TRUE, TryOneFile]; FOR dirs: LIST OF PATH _ module.possiblePrincipalDirectories, dirs.rest WHILE dirs # NIL AND foundFile = NIL DO TryOneDir[dirs.first]; ENDLOOP; FOR dirs: LIST OF PATH _ module.moduleSet.otherDirectories, dirs.rest WHILE dirs # NIL AND foundFile = NIL DO TryOneDir[dirs.first]; ENDLOOP; IF foundFile = NIL THEN BEGIN module.cSourceFailed _ TRUE; module.failureTime _ BasicTime.Now[]; ShowFailureReport["c source", module]; END ELSE BEGIN cName: PATH _ SystemInterface.GetNameOfFile[foundFile]; parts: NameParts _ GetNamePartsFromFullPathName[cName]; IF foundFile # foundPossibleFile THEN ERROR; <<(this depends on the file caching mechanism in FileSet, to that we get only one file for each name.)>> module.cInfo _ foundCInfo; module.possiblePrincipalDirectories _ AddAName[parts.principalDirectory, module.possiblePrincipalDirectories]; module.cSourceFailed _ FALSE; SystemInterface.ShowReport[Rope.Cat[" found ", PFS.RopeFromPath[cName]], $normal]; END; END; END; RETURN[module.cInfo]; END; GetJMPI: PROC[module: CedarModule] RETURNS[MOF.JointMobParsedInfo] = BEGIN IF module.jmpi = NIL AND NOT (module.jmpiFailed AND BasicTime.Period[module.failureTime, module.moduleSet.flushTime] < 0) THEN BEGIN mob: MA.MobCookie _ GetMob[module]; embeddedModule: ObjF.Module _ GetModule[module]; whole: ObjF.Parsed _ GetParsed[module]; IF mob # NIL AND embeddedModule # NIL AND whole # NIL THEN module.jmpi _ MOF.CreateJointMobParsedInfo[mob, whole, embeddedModule]; IF module.jmpi = NIL THEN {module.jmpiFailed _ TRUE; module.failureTime _ BasicTime.Now[]} END; RETURN[module.jmpi]; END; GetParsed: PROC[module: CedarModule] RETURNS[ObjF.Parsed] = BEGIN IF module.whole = NIL AND NOT (module.wholeFailed AND BasicTime.Period[module.failureTime, module.moduleSet.flushTime] < 0) THEN BEGIN [] _ GetModule[module]; IF module.whole = NIL THEN BEGIN module.wholeFailed _ TRUE; module.failureTime _ BasicTime.Now[]; ShowFailureReport["whole", module]; END; END; RETURN[module.whole]; END; GetModule: PROC[module: CedarModule] RETURNS[ObjF.Module] = BEGIN IF module.module = NIL AND NOT (module.moduleFailed AND BasicTime.Period[module.failureTime, module.moduleSet.flushTime] < 0) THEN BEGIN [] _ GetMob[module]; <> IF module.possibleNameStems # NIL AND module.mob # NIL THEN BEGIN foundFile: CirioFile _ NIL; -- tentative foundDotO: ObjF.Parsed _ NIL; -- tentative foundModule: ObjF.Module _ NIL; -- tentative foundPossibleFile: CirioFile _ NIL; -- tentative <> TryOneFile: PROC[info: SystemInterface.CirioFileInfo] RETURNS[thisIsIt: BOOLEAN _ FALSE] = BEGIN IF module.mobStamp = NIL THEN ERROR ELSE BEGIN possibleFile: CirioFile _ SystemInterface.GetCirioFile[module.moduleSet.fileSet, info.fullName, info.uniqueID]; possibleDotO: ObjF.Parsed _ ObjF.CreateParsed[possibleFile]; <> possibleModule: ObjF.Module _ FallBackFindModule[possibleDotO, 0]; vsInfo: REF ObjF.VersionStampInfo _ ObjF.FindVersionStamp[possibleModule]; recoveredStamp: REF RecoveredVersionStamp _ IF vsInfo = NIL OR vsInfo.contents = NIL THEN NIL ELSE ConvertDotOFormatVersionStampToMobFormat[vsInfo.contents]; IF recoveredStamp # NIL AND module.mobStamp # NIL AND recoveredStamp.mobStamp = module.mobStamp^ THEN BEGIN foundDotO _ possibleDotO; foundModule _ possibleModule; foundPossibleFile _ possibleFile; RETURN[TRUE] END ELSE RETURN[FALSE]; END; END; TryOneDir: PROC[dir: PATH] = BEGIN rdir: Rope.ROPE _ PFS.RopeFromPath[PFSNames.EnsureDirectory[dir]]; FOR stems: LIST OF PATH _ module.possibleNameStems, stems.rest WHILE stems # NIL AND foundFile = NIL DO <> patterns: LIST OF PATH _ LIST[ PFS.PathFromRope[Rope.Cat[rdir, "debug/", PFS.RopeFromPath[stems.first], ".c2c.o"]], PFS.PathFromRope[Rope.Cat[rdir, "debug/", PFS.RopeFromPath[stems.first], ".o"]], PFS.PathFromRope[Rope.Cat[rdir, "debug/", PFS.RopeFromPath[stems.first]]], PFS.PathFromRope[Rope.Cat[rdir, "sun4-debug/", PFS.RopeFromPath[stems.first], ".c2c.o", "*"]], PFS.PathFromRope[Rope.Cat[rdir, "sun4-debug/", PFS.RopeFromPath[stems.first], ".o", "*"]], PFS.PathFromRope[Rope.Cat[rdir, "sun4-debug/", PFS.RopeFromPath[stems.first], "*"]], PFS.PathFromRope[Rope.Cat[rdir, "sun4/", PFS.RopeFromPath[stems.first], ".c2c.o", "*"]], PFS.PathFromRope[Rope.Cat[rdir, "sun4/", PFS.RopeFromPath[stems.first], ".o", "*"]], PFS.PathFromRope[Rope.Cat[rdir, "sun4/", PFS.RopeFromPath[stems.first], "*"]], PFS.PathFromRope[Rope.Cat[rdir, PFS.RopeFromPath[stems.first], ".c2c.o", "*"]], PFS.PathFromRope[Rope.Cat[rdir, PFS.RopeFromPath[stems.first], ".o", "*"]], PFS.PathFromRope[Rope.Cat[rdir, PFS.RopeFromPath[stems.first], "*"]]]; FOR ps: LIST OF PATH _ patterns, ps.rest WHILE ps # NIL AND foundFile = NIL DO foundFile _ SystemInterface.GenCirioFilesForInfo[module.moduleSet.fileSet, ps.first, TryOneFile]; ENDLOOP; ENDLOOP; END; ShowSearchReport["module", module]; FOR dirs: LIST OF PATH _ module.moduleSet.searchPaths, dirs.rest WHILE dirs # NIL AND foundFile = NIL DO TryOneDir[dirs.first]; ENDLOOP; IF foundFile = NIL THEN [] _ SystemInterface.GenVersionMapFilesForInfo[module.moduleSet.fileSet, $Executable, <>MobDefs.NullVersion, module.possibleNameStems, LIST[".c2c.o", ".o", ""], TRUE, TryOneFile]; FOR dirs: LIST OF PATH _ module.possiblePrincipalDirectories, dirs.rest WHILE dirs # NIL AND foundFile = NIL DO TryOneDir[dirs.first]; ENDLOOP; FOR dirs: LIST OF PATH _ module.moduleSet.otherDirectories, dirs.rest WHILE dirs # NIL AND foundFile = NIL DO TryOneDir[dirs.first]; ENDLOOP; IF foundFile = NIL THEN BEGIN module.moduleFailed _ TRUE; module.failureTime _ BasicTime.Now[]; ShowFailureReport["module", module]; END ELSE BEGIN moduleName: PATH _ SystemInterface.GetNameOfFile[foundFile]; parts: NameParts _ GetNamePartsFromFullPathName[moduleName]; IF foundFile # foundPossibleFile THEN ERROR; <<(this depends on the file caching mechanism in FileSet, to that we get only one file for each name.)>> module.module _ foundModule; module.whole _ foundDotO; module.possiblePrincipalDirectories _ AddAName[parts.principalDirectory, module.possiblePrincipalDirectories]; module.moduleFailed _ FALSE; SystemInterface.ShowReport[Rope.Cat[" found ", PFS.RopeFromPath[moduleName]], $normal]; END; END; END; RETURN[module.module]; END; GetMob: PROC[module: CedarModule] RETURNS[MA.MobCookie] = <> BEGIN modules: CedarModuleSet _ module.moduleSet; IF module.mobStamp = NIL AND module.sourceStamp = NIL THEN ERROR; IF module.mob = NIL AND NOT (module.mobFailed AND BasicTime.Period[module.failureTime, modules.flushTime] < 0) THEN BEGIN <> otherModule: CedarModule; base: RopeParts.RopePart _ emptyRopePart; mobKey, srcKey: RefTab.Key; IF module.mobStamp#NIL THEN { mobKey _ CreateVSKey[module.mobStamp^, emptyRopePart]; otherModule _ NARROW[RefTab.Fetch[modules.vsHash.table, mobKey].val]; mobKey _ mobKey}; IF otherModule=NIL AND module.sourceStamp#NIL THEN { nameStems: LIST OF PATH _ IF module.possibleNameStems # NIL THEN module.possibleNameStems ELSE module.originalPossibleNameStems; baseComponent: PFSNames.Component; FOR stems: LIST OF PATH _ nameStems, stems.rest WHILE stems#NIL AND otherModule=NIL DO baseComponent _ PFSNames.ShortName[stems.first]; base _ [baseComponent.name.base, baseComponent.name.start, baseComponent.name.len]; srcKey _ CreateVSKey[module.sourceStamp^, base]; otherModule _ NARROW[RefTab.Fetch[modules.vsHash.table, srcKey].val]; ENDLOOP; }; <> IF otherModule # NIL AND otherModule # module THEN -- good, lets combine info BEGIN -- we must produce a single module, while checking for inconsistencies incompatible: BOOLEAN _ FALSE; -- tentative IF module.moduleSet # otherModule.moduleSet THEN ERROR; IF module.mobStamp = NIL THEN module.mobStamp _ otherModule.mobStamp; IF otherModule.mobStamp = NIL THEN otherModule.mobStamp _ module.mobStamp; IF module.mobStamp # NIL AND module.mobStamp^ # otherModule.mobStamp^ THEN ERROR; IF module.sourceStamp = NIL THEN module.sourceStamp _ otherModule.sourceStamp; IF otherModule.sourceStamp = NIL THEN otherModule.sourceStamp _ module.sourceStamp; IF module.sourceStamp # NIL AND module.sourceStamp^ # otherModule.sourceStamp^ THEN ERROR; FOR ppds: LIST OF PATH _ otherModule.possiblePrincipalDirectories, ppds.rest WHILE ppds # NIL DO module.possiblePrincipalDirectories _ AddAName[ppds.first, module.possiblePrincipalDirectories]; ENDLOOP; FOR ppds: LIST OF PATH _ module.possiblePrincipalDirectories, ppds.rest WHILE ppds # NIL DO otherModule.possiblePrincipalDirectories _ AddAName[ppds.first, otherModule.possiblePrincipalDirectories]; ENDLOOP; FOR pns: LIST OF PATH _ otherModule.possibleNameStems, pns.rest WHILE pns # NIL DO module.possibleNameStems _ AddAName[pns.first, module.possibleNameStems]; ENDLOOP; FOR pns: LIST OF PATH _ module.possibleNameStems, pns.rest WHILE pns # NIL DO otherModule.possibleNameStems _ AddAName[pns.first, otherModule.possibleNameStems]; ENDLOOP; IF BasicTime.Period[module.failureTime, otherModule.failureTime] > 0 THEN otherModule.failureTime _ module.failureTime ELSE module.failureTime _ otherModule.failureTime; -- (earliest failure time to both) IF NOT module.mesaSourceFailed OR NOT otherModule.mesaSourceFailed THEN module.mesaSourceFailed _ otherModule.mesaSourceFailed _ FALSE; IF NOT module.mobFileFailed OR NOT otherModule.mobFileFailed THEN module.mobFileFailed _ otherModule.mobFileFailed _ FALSE; IF NOT module.mobFailed OR NOT otherModule.mobFailed THEN module.mobFailed _ otherModule.mobFailed _ FALSE; IF NOT module.cSourceFailed OR NOT otherModule.cSourceFailed THEN module.cSourceFailed _ otherModule.cSourceFailed _ FALSE; IF NOT module.jmpiFailed OR NOT otherModule.jmpiFailed THEN module.jmpiFailed _ otherModule.jmpiFailed _ FALSE; IF NOT module.moduleFailed OR NOT otherModule.moduleFailed THEN module.moduleFailed _ otherModule.moduleFailed _ FALSE; IF NOT module.wholeFailed OR NOT otherModule.wholeFailed THEN module.wholeFailed _ otherModule.wholeFailed _ FALSE; IF module.mesaSource # NIL AND otherModule.mesaSource # NIL THEN incompatible _ module.mesaSource # otherModule.mesaSource; IF module.mesaSource = NIL THEN module.mesaSource _ otherModule.mesaSource; IF otherModule.mesaSource = NIL THEN otherModule.mesaSource _ module.mesaSource; IF module.jmpi # NIL AND otherModule.jmpi # NIL THEN incompatible _ module.jmpi # otherModule.jmpi; IF module.jmpi = NIL THEN module.jmpi _ otherModule.jmpi; IF otherModule.jmpi = NIL THEN otherModule.jmpi _ module.jmpi; IF module.mobFile # NIL AND otherModule.mobFile # NIL THEN incompatible _ module.mobFile # otherModule.mobFile; IF module.mobFile = NIL THEN module.mobFile _ otherModule.mobFile; IF otherModule.mobFile = NIL THEN otherModule.mobFile _ module.mobFile; IF module.mob # NIL AND otherModule.mob # NIL THEN incompatible _ module.mob # otherModule.mob; IF module.mob = NIL THEN module.mob _ otherModule.mob; IF otherModule.mob = NIL THEN otherModule.mob _ module.mob; IF module.cInfo # NIL AND otherModule.cInfo # NIL THEN incompatible _ module.cInfo # otherModule.cInfo; IF module.cInfo = NIL THEN module.cInfo _ otherModule.cInfo; IF otherModule.cInfo = NIL THEN otherModule.cInfo _ module.cInfo; IF module.module # NIL AND otherModule.module # NIL THEN incompatible _ module.module # otherModule.module; IF module.module = NIL THEN module.module _ otherModule.module; IF otherModule.module = NIL THEN otherModule.module _ module.module; IF module.whole # NIL AND otherModule.whole # NIL THEN incompatible _ module.whole # otherModule.whole; IF module.whole = NIL THEN module.whole _ otherModule.whole; IF otherModule.whole = NIL THEN otherModule.whole _ module.whole; IF NOT incompatible THEN module^ _ otherModule^; END; <> IF module.mob = NIL THEN -- we still have to find the mob BEGIN nameStems: LIST OF PATH _ IF module.possibleNameStems # NIL THEN module.possibleNameStems ELSE module.originalPossibleNameStems; IF nameStems # NIL THEN BEGIN foundMob: MA.MobCookie _ NIL; -- tentative foundPossibleFile: CirioFile _ NIL; -- tentative foundCreateTime: BasicTime.GMT _ BasicTime.earliestGMT; -- tentative <> TryOneFile: PROC[info: SystemInterface.CirioFileInfo] RETURNS[thisIsIt: BOOLEAN _ FALSE] = BEGIN possibleFile: CirioFile _ SystemInterface.GetCirioFile[modules.fileSet, info.fullName, info.uniqueID]; IF module.mobStamp = NIL AND module.sourceStamp = NIL THEN <> BEGIN mob: MA.MobCookie _ MA.CreateMobCookie[possibleFile ! MobAccess.MobError => { SystemInterface.ShowReport[IO.PutFR["\tbad mob %g", [rope[PFS.RopeFromPath[info.fullName]]] ], IF debugSearch THEN $urgent ELSE $debug]; GOTO failure}]; SystemInterface.ShowReport[Rope.Cat["accepting ", PFS.RopeFromPath[info.fullName], " without any version checking"], $normal]; IF foundPossibleFile = NIL OR (BasicTime.Period[foundCreateTime, info.uniqueID.egmt.time] > 0) THEN <> BEGIN foundMob _ mob; foundPossibleFile _ possibleFile; foundCreateTime _ info.uniqueID.egmt.time; RETURN[TRUE] END; RETURN[FALSE] END ELSE BEGIN mob: MA.MobCookie _ MA.CreateMobCookie[possibleFile ! MobAccess.MobError => { SystemInterface.ShowReport[IO.PutFR["\tbad mob %g", [rope[PFS.RopeFromPath[info.fullName]]] ], IF debugSearch THEN $urgent ELSE $debug]; GOTO failure}]; <> mobStamp: MobDefs.VersionStamp _ MA.ReadMobVersionStamp[mob]; mobSourceStamp: MobDefs.VersionStamp _ MA.ReadSourceVersionStamp[mob]; ok: BOOLEAN _ FALSE; -- tentative; IF module.mobStamp # NIL AND module.mobStamp^ = mobStamp THEN ok _ TRUE; IF module.sourceStamp # NIL AND module.sourceStamp^ = mobSourceStamp THEN ok _ TRUE; ok _ ok AND (foundPossibleFile = NIL OR (BasicTime.Period[foundCreateTime, info.uniqueID.egmt.time] > 0)); <> IF debugSearch THEN SystemInterface.ShowReport[IO.PutFLR["\t?name=%g,\n\tmobStamp=%08x%08x, sourceStamp=%08x%08x,\n\tcreate=%g, ok=%g.", LIST[ [rope[PFS.RopeFromPath[info.fullName]]], [cardinal[mobStamp[0]]], [cardinal[mobStamp[1]]], [cardinal[mobSourceStamp[0]]], [cardinal[mobSourceStamp[1]]], [time[info.uniqueID.egmt.time]], [boolean[ok]] ]], $urgent]; IF ok THEN BEGIN foundMob _ mob; foundPossibleFile _ possibleFile; foundCreateTime _ info.uniqueID.egmt.time; RETURN[TRUE]; END; RETURN[FALSE]; END; EXITS failure => RETURN[FALSE]; END; TryOneDir: PROC[dir: PATH] = BEGIN FOR stems: LIST OF PATH _ nameStems, stems.rest WHILE stems # NIL AND foundPossibleFile = NIL DO mobFileNamePattern: PATH _ PFS.PathFromRope[Rope.Cat[PFS.RopeFromPath[stems.first], ".mob", "*"]]; mobFileNamePattern _ mobFileNamePattern.ExpandName[dir]; IF debugSearch THEN SystemInterface.ShowReport[IO.PutFR["\tSearching file pattern %g.", [rope[PFS.RopeFromPath[mobFileNamePattern]]] ], $urgent]; [] _ SystemInterface.GenCirioFilesForInfo[modules.fileSet, mobFileNamePattern, TryOneFile]; ENDLOOP; END; ShowSearchReport["mob", module]; IF debugSearch THEN SystemInterface.ShowReport[IO.PutFR["\twith mob stamp %g and source stamp %g.", [rope[DescribeRefStamp[module.mobStamp]]], [rope[DescribeRefStamp[module.sourceStamp]]] ], $urgent]; FOR dirs: LIST OF PATH _ modules.searchPaths, dirs.rest WHILE dirs # NIL AND foundPossibleFile = NIL DO IF debugSearch THEN SystemInterface.ShowReport[IO.PutFR["\tSearching search dir %g.", [rope[PFS.RopeFromPath[dirs.first]]] ], $urgent]; TryOneDir[dirs.first]; ENDLOOP; IF foundPossibleFile = NIL THEN { IF debugSearch THEN SystemInterface.ShowReport["\tSearching version maps.", $urgent]; foundPossibleFile _ SystemInterface.GenVersionMapFilesForInfo[modules.fileSet, $Intermediate, MobDefs.NullVersion, nameStems, LIST[".mob"], TRUE, TryOneFile]}; FOR dirs: LIST OF PATH _ module.possiblePrincipalDirectories, dirs.rest WHILE dirs # NIL AND foundPossibleFile = NIL DO IF debugSearch THEN SystemInterface.ShowReport[IO.PutFR["\tSearching possible principle dir %g.", [rope[PFS.RopeFromPath[dirs.first]]] ], $urgent]; TryOneDir[dirs.first]; ENDLOOP; FOR dirs: LIST OF PATH _ modules.otherDirectories, dirs.rest WHILE dirs # NIL AND foundPossibleFile = NIL DO IF debugSearch THEN SystemInterface.ShowReport[IO.PutFR["\tSearching other dir %g.", [rope[PFS.RopeFromPath[dirs.first]]] ], $urgent]; TryOneDir[dirs.first]; ENDLOOP; IF foundPossibleFile = NIL THEN BEGIN module.mobFailed _ TRUE; module.failureTime _ BasicTime.Now[]; ShowFailureReport["mob", module]; END ELSE BEGIN mobName: PATH _ SystemInterface.GetNameOfFile[foundPossibleFile]; parts: NameParts _ GetNamePartsFromFullPathName[mobName]; module.mob _ foundMob; module.possiblePrincipalDirectories _ AddAName[parts.principalDirectory, module.possiblePrincipalDirectories]; module.mobStamp _ NEW[MobDefs.VersionStamp _ MA.ReadMobVersionStamp[module.mob]]; IF module.sourceStamp = NIL THEN { module.sourceStamp _ NEW[MobDefs.VersionStamp _ MA.ReadSourceVersionStamp[module.mob]]; base _ RopeParts.InlineMake[parts.nameStem]; srcKey _ CreateVSKey[module.sourceStamp^, base]; [] _ RefTab.Store[modules.vsHash.table, srcKey, module]; }; IF module.possibleNameStems = NIL THEN module.possibleNameStems _ LIST[PFS.PathFromRope[parts.nameStem]]; module.mobFailed _ FALSE; mobKey _ CreateVSKey[module.mobStamp^, emptyRopePart]; IF RefTab.Fetch[modules.vsHash.table, mobKey].val = NIL THEN {IF NOT RefTab.Store[modules.vsHash.table, mobKey, module] THEN ERROR}; SystemInterface.ShowReport[Rope.Cat[" found ", PFS.RopeFromPath[mobName]], $normal]; END; END; END; END; RETURN[module.mob]; END; GetDotO: PUBLIC PROC [targetData: REF ANY, dotOPathRope, dotORope: Rope.ROPE, dotOId: CARD, getDotOId: PROC [ObjF.Parsed] RETURNS [CARD]] RETURNS [ObjF.Parsed] = { modules: CedarModuleSet _ NARROW[targetData]; RETURN [GetDotOInner[modules, dotOPathRope, dotORope, dotOId, getDotOId]]; }; GetDotOInner: PROC [moduleSet: CedarModuleSet, dotOPathRope, dotORope: Rope.ROPE, dotOId: CARD, getDotOId: PROC [ObjF.Parsed] RETURNS [CARD]] RETURNS [ObjF.Parsed] = { foundFile: CirioFile _ NIL; -- tentative foundDotO: ObjF.Parsed _ NIL; -- tentative foundPossibleFile: CirioFile _ NIL; -- tentative TryOneFile: PROC [info: SystemInterface.CirioFileInfo] RETURNS [thisIsIt: BOOLEAN _ FALSE] = { possibleFile: CirioFile _ SystemInterface.GetCirioFile[moduleSet.fileSet, info.fullName, info.uniqueID]; possibleDotO: ObjF.Parsed _ ObjF.CreateParsed[possibleFile]; IF getDotOId[possibleDotO] = dotOId THEN { foundDotO _ possibleDotO; foundPossibleFile _ possibleFile; RETURN[TRUE] }; RETURN[FALSE]; }; TryOneDir: PROC [dir: PATH] = { rdir: Rope.ROPE _ PFS.RopeFromPath[PFSNames.EnsureDirectory[dir]]; <> patterns: LIST OF PATH _ LIST[ PFS.PathFromRope[Rope.Cat[rdir, dotORope]], PFS.PathFromRope[Rope.Cat[rdir, "debug/", dotORope]], PFS.PathFromRope[Rope.Cat[rdir, "sun4-debug/", dotORope, "*"]], PFS.PathFromRope[Rope.Cat[rdir, "sun4/", dotORope, "*"]] ]; FOR ps: LIST OF PATH _ patterns, ps.rest WHILE ps # NIL AND foundFile = NIL DO foundFile _ SystemInterface.GenCirioFilesForInfo[moduleSet.fileSet, ps.first, TryOneFile]; ENDLOOP; }; SystemInterface.ShowReport[Rope.Concat["searching for ", dotORope], $normal]; FOR dirs: LIST OF PATH _ moduleSet.searchPaths, dirs.rest WHILE dirs # NIL AND foundFile = NIL DO TryOneDir[dirs.first]; ENDLOOP; IF foundFile = NIL THEN [] _ SystemInterface.GenVersionMapFilesForInfo[moduleSet.fileSet, $Executable, MobDefs.NullVersion, LIST[PFS.PathFromRope[dotORope]], NIL, TRUE, TryOneFile]; FOR dirs: LIST OF PATH _ moduleSet.otherDirectories, dirs.rest WHILE dirs # NIL AND foundFile = NIL DO TryOneDir[dirs.first]; ENDLOOP; IF foundFile = NIL THEN SystemInterface.ShowReport[Rope.Cat["unable to find module for ", dotORope], $normal] ELSE { moduleName: PATH _ SystemInterface.GetNameOfFile[foundFile]; IF foundFile # foundPossibleFile THEN ERROR; <<(this depends on the file caching mechanism in FileSet, to that we get only one file for each name.)>> SystemInterface.ShowReport[Rope.Cat[" found ", PFS.RopeFromPath[moduleName]], $normal]; }; RETURN [foundDotO]; }; <> FallBackFindModule: PROC[whole: ObjF.Parsed, relativePC: CARD] RETURNS[ObjF.Module] = BEGIN RETURN[ObjF.ModuleFromParsedAndPC[whole, [[0,""], relativePC]]] END; <> VSHashTable: TYPE = REF VSHashTableBody; VSHashTableBody: TYPE = RECORD[table: RefTab.Ref]; VSHashEntryKey: TYPE = RECORD[versionStamp: MobDefs.VersionStamp, base: RopeParts.RopePart]; emptyRopePart: RopeParts.RopePart _ [base: "", start: 0, len: 0]; CreateVSHashTable: PROC RETURNS[VSHashTable] = {RETURN[NEW[VSHashTableBody _ [table: RefTab.Create[equal: VSKeyEqualProc, hash: VSKeyHashProc]]]]}; CreateVSKey: PROC[stamp: MobDefs.VersionStamp, base: RopeParts.RopePart] RETURNS[RefTab.Key] = {RETURN[NEW[VSHashEntryKey _ [versionStamp: stamp, base: base]]]}; VSKeyEqualProc: PROC[key1, key2: RefTab.Key] RETURNS[BOOL] = BEGIN vs1: REF VSHashEntryKey _ NARROW[key1]; vs2: REF VSHashEntryKey _ NARROW[key2]; RETURN[(vs1^.versionStamp = vs2^.versionStamp) AND (RopeParts.Equal[vs1^.base, vs2^.base])]; END; VSKeyHashProc: PROC[key: RefTab.Key] RETURNS[CARDINAL] = BEGIN vs: REF VSHashEntryKey _ NARROW[key]; word0: PBasics.LongNumber _ LOOPHOLE[vs^.versionStamp[0]]; word1: PBasics.LongNumber _ LOOPHOLE[vs^.versionStamp[1]]; RETURN[RopeParts.Hash[base: vs^.base, seed: PBasics.BITXOR[PBasics.BITXOR[word0.lo, word0.hi], PBasics.BITXOR[word1.lo, word1.hi]]]]; END; <<>> <> GetNamePartsFromFullPathName: PUBLIC PROC [fullPathName: PATH] RETURNS [NameParts] = { principalDirectory: PATH; sun4: PATH _ PFSNames.EmptyPath; -- tentative c2c: PATH _ PFSNames.EmptyPath; -- tentative shortComp: PFSNames.Component _ fullPathName.ShortName; shortName: ROPE _ shortComp.ComponentRope; directoryPath: PATH _ fullPathName.Directory; <<>> <> IF directoryPath # PFSNames.EmptyPath AND directoryPath # NIL AND directoryPath.ComponentCount # 0 THEN BEGIN lastDirectory: PFSNames.Component _ directoryPath.Fetch[directoryPath.ComponentCount - 1]; <> lastDirectoryRope: Rope.ROPE _ lastDirectory.ComponentRope; IF Rope.Equal["sun4", lastDirectoryRope] OR Rope.Equal["sun4-o3", lastDirectoryRope] OR Rope.Equal["sun4o3", lastDirectoryRope, FALSE] THEN <> directoryPath _ directoryPath.Parent; END; principalDirectory _ directoryPath; <> {lastDot: INT _ Rope.FindBackward[shortName, "."]; IF lastDot > -1 AND lastDot+1 < Rope.Length[shortName] AND Rope.Fetch[shortName, lastDot+1] = '~ THEN -- remove the version shortName _ Rope.Substr[shortName, 0, lastDot]; }; <> {lastDot: INT _ Rope.FindBackward[shortName, "."]; secondToLastDot: INT _ IF lastDot <= 0 THEN -1 ELSE Rope.FindBackward[shortName, ".", lastDot-1]; IF secondToLastDot > -1 AND Rope.Equal["c2c", Rope.Substr[shortName, secondToLastDot+1, lastDot-1-secondToLastDot]] THEN { shortName _ Rope.Replace[shortName, secondToLastDot, 4, ""]; c2c _ PFS.PathFromRope[".c2c"]}; }; <> {lastDot: INT _ Rope.FindBackward[shortName, "."]; IF lastDot > -1 THEN shortName _ Rope.Substr[shortName, 0, lastDot]; }; RETURN[[ principalDirectory, <> shortName <> ]]; }; <<>> <> CFileInfo: TYPE = REF CFileInfoBody; CFileInfoBody: TYPE = RECORD[ file: CirioFile, sourcePosSeq: SourcePosSeq, lineNumSeq: LineNumSeq, versionStamp: Rope.ROPE]; SourcePosSeq: TYPE = REF SourcePosSeqBody; SourcePosSeqBody: TYPE = RECORD[ SEQUENCE nSourceMacros: CARDINAL OF SourcePosMacro]; LineNumSeq: TYPE = REF LineNumSeqBody; LineNumSeqBody: TYPE = RECORD[ SEQUENCE nSourceMacros: CARDINAL OF SourcePosMacro]; SourcePosMacro: TYPE = RECORD[pos: CARD, nChars: CARD, lineNum: CARD]; <> <<>> <> <<>> <> <<>> <> <> LookupMesaSourcePos: PROC[info: CFileInfo, pos: CARD] RETURNS[cLineNum: CARD] = BEGIN FOR I: CARDINAL DECREASING IN [0..info.sourcePosSeq.nSourceMacros) DO IF info.sourcePosSeq[I].pos <= pos THEN RETURN[info.sourcePosSeq[I].lineNum] ENDLOOP; IF info.sourcePosSeq.nSourceMacros = 0 THEN RETURN[0]; RETURN[info.sourcePosSeq[0].lineNum] END; <<>> <> LookupCLineNum: PROC[info: CFileInfo, cLineNum: CARD] RETURNS[pos: CARD] = BEGIN FOR I: CARDINAL DECREASING IN [0..info.lineNumSeq.nSourceMacros) DO IF info.lineNumSeq[I].lineNum <= cLineNum THEN RETURN[info.lineNumSeq[I].pos] ENDLOOP; IF info.lineNumSeq.nSourceMacros = 0 THEN RETURN[0]; RETURN[info.lineNumSeq[0].pos] END; CompareSourceMacrosByPos: PROC[ref1: REF ANY, ref2: REF ANY] RETURNS [Basics.Comparison] = BEGIN sm1: REF SourcePosMacro _ NARROW[ref1]; sm2: REF SourcePosMacro _ NARROW[ref2]; IF sm1.pos < sm2.pos THEN RETURN[less]; IF sm1.pos > sm2.pos THEN RETURN[greater]; <> <<(however, I don't believe that this can happen)>> IF sm1.lineNum < sm2.lineNum THEN RETURN[less]; IF sm1.lineNum > sm2.lineNum THEN RETURN[greater]; RETURN[equal]; END; CompareSourceMacrosByCLineNum: PROC[ref1: REF ANY, ref2: REF ANY] RETURNS [Basics.Comparison] = BEGIN sm1: REF SourcePosMacro _ NARROW[ref1]; sm2: REF SourcePosMacro _ NARROW[ref2]; IF sm1.lineNum < sm2.lineNum THEN RETURN[less]; IF sm1.lineNum > sm2.lineNum THEN RETURN[greater]; <> <<(I don't believe that this can happen)>> IF sm1.pos < sm2.pos THEN RETURN[less]; IF sm1.pos > sm2.pos THEN RETURN[greater]; RETURN[equal]; END; ScanCFileForVersionStamp: PROC[cFile: CirioFile] RETURNS[versionStamp: Rope.ROPE _ NIL] = BEGIN source: IO.STREAM _ SystemInterface.GetStreamForFile[cFile]; BEGIN ENABLE UNWIND => SystemInterface.ReleaseStreamForFile[cFile, source]; buffer: REF TEXT _ NIL; smKey: Rope.ROPE _ "SOURCE("; smKeyLength: CARD _ Rope.Length[smKey]; vsKey: Rope.ROPE _ Rope.Cat["static char versionStamp[] = \"@", "(#)", "mob_version ["]; <> vsKeyLength: CARD _ Rope.Length[vsKey]; FOR ln: CARD _ 1, ln+1 WHILE NOT IO.EndOf[source] DO buffer _ IO.GetLine[source, buffer]; IF buffer[0] = 's THEN -- possible version stamp hit BEGIN line: Rope.ROPE _ Rope.FromRefText[buffer]; IF Rope.Equal[vsKey, Rope.Substr[line, 0, vsKeyLength]] THEN -- we have a hit BEGIN quote1: INT _ Rope.Index[line, 0, "\""]; quote2: INT _ Rope.Index[line, quote1+1, "\""]; IF quote2 = Rope.Length[line]-2 THEN -- a final consistency check versionStamp _ Rope.Substr[line, quote1+1, quote2-quote1-1]; END END; IF versionStamp # NIL THEN EXIT; ENDLOOP; END; SystemInterface.ReleaseStreamForFile[cFile, source]; END; <> CreateCFileInfo: PROC[cFile: CirioFile] RETURNS[CFileInfo] = BEGIN list1: LIST OF REF ANY _ NIL; list2: LIST OF REF ANY _ NIL; nMacros: INTEGER _ 0; sortedList: LIST OF REF ANY _ NIL; sourcePosSeq: SourcePosSeq; lineNumSeq: LineNumSeq; versionStamp: Rope.ROPE _ NIL; SeeOnePosition: PROC[sp: CARD, nChars: CARD, ln: CARD] = BEGIN list1 _ CONS[NEW[SourcePosMacro_[sp, nChars, ln]], list1]; list2 _ CONS[NEW[SourcePosMacro_[sp, nChars, ln]], list2]; nMacros _ nMacros+1; END; versionStamp _ GenMesaSourcePositionMacros[cFile, SeeOnePosition]; sortedList _ List.Sort[list1, CompareSourceMacrosByPos]; sourcePosSeq _ NEW[SourcePosSeqBody[nMacros]]; FOR I: INTEGER IN [0..nMacros) DO macro: REF SourcePosMacro _ NARROW[sortedList.first]; sourcePosSeq[I] _ macro^; sortedList _ sortedList.rest; ENDLOOP; sortedList _ List.Sort[list2, CompareSourceMacrosByCLineNum]; lineNumSeq _ NEW[LineNumSeqBody[nMacros]]; FOR I: INTEGER IN [0..nMacros) DO macro: REF SourcePosMacro _ NARROW[sortedList.first]; lineNumSeq[I] _ macro^; sortedList _ sortedList.rest; ENDLOOP; RETURN[NEW[CFileInfoBody_[cFile, sourcePosSeq, lineNumSeq, versionStamp]]] END; <<>> <> GetCFileVersionStamp: PROC[info: CFileInfo] RETURNS[Rope.ROPE] = {RETURN[info.versionStamp]}; GenMesaSourcePositionMacros: PROC[cFile: CirioFile, SeeOnePosition: PROC[sp: CARD, nChars: CARD, ln: CARD]] RETURNS[versionStamp: Rope.ROPE _ NIL] = BEGIN source: IO.STREAM _ SystemInterface.GetStreamForFile[cFile]; BEGIN ENABLE UNWIND => SystemInterface.ReleaseStreamForFile[cFile, source]; buffer: REF TEXT _ NIL; smKey: Rope.ROPE _ "SOURCE("; smKeyLength: CARD _ Rope.Length[smKey]; vsKey: Rope.ROPE _ Rope.Cat["static char versionStamp[] = \"@", "(#)", "mob_version ["]; <> vsKeyLength: CARD _ Rope.Length[vsKey]; FOR ln: CARD _ 1, ln+1 WHILE NOT IO.EndOf[source] DO buffer _ IO.GetLine[source, buffer]; IF buffer[0] = 'S THEN -- possible SourcePositionMacro hit BEGIN line: Rope.ROPE _ Rope.FromRefText[buffer]; IF Rope.Equal[smKey, Rope.Substr[line, 0, smKeyLength]] THEN -- we have a hit BEGIN x: CARD _ smKeyLength; sp: CARD _ 0; nChars: CARD _ 0; DO IF buffer[x] = ', THEN EXIT; sp _ sp*10 + ORD[buffer[x]] - ORD['0]; x _ x+1; ENDLOOP; WHILE buffer[x] = ', OR buffer[x] = ' DO x _ x+1 ENDLOOP; DO IF buffer[x] = ') THEN EXIT; nChars _ nChars*10 + ORD[buffer[x]] - ORD['0]; x _ x+1; ENDLOOP; SeeOnePosition[sp, nChars, ln]; END; END; IF buffer[0] = 's THEN -- possible version stamp hit BEGIN line: Rope.ROPE _ Rope.FromRefText[buffer]; IF Rope.Equal[vsKey, Rope.Substr[line, 0, vsKeyLength]] THEN -- we have a hit BEGIN quote1: INT _ Rope.Index[line, 0, "\""]; quote2: INT _ Rope.Index[line, quote1+1, "\""]; IF quote2 = Rope.Length[line]-2 THEN -- a final consistency check versionStamp _ Rope.Substr[line, quote1+1, quote2-quote1-1]; END END; ENDLOOP; END; SystemInterface.ReleaseStreamForFile[cFile, source]; END; <> <<>> <> <<>> AddAName: PROC[newName: PATH, names: LIST OF PATH] RETURNS[LIST OF PATH] = BEGIN FOR nms: LIST OF PATH _ names, nms.rest WHILE nms # NIL DO IF nms.first.Equal[newName] THEN RETURN[names]; ENDLOOP; RETURN[CONS[newName, names]]; END; ShowSearchReport: PROC[target: Rope.ROPE, module: CedarModule] = BEGIN names: Rope.ROPE _ NIL; FOR stems: LIST OF PATH _ IF module.possibleNameStems # NIL THEN module.possibleNameStems ELSE module.originalPossibleNameStems, stems.rest WHILE stems # NIL DO IF names # NIL THEN names _ Rope.Cat[names, " or "]; names _ Rope.Cat[names, PFS.RopeFromPath[stems.first]]; ENDLOOP; SystemInterface.ShowReport[Rope.Cat["searching for ", target, " for ", names], $normal]; END; ShowFailureReport: PROC[target: Rope.ROPE, module: CedarModule] = BEGIN names: Rope.ROPE _ NIL; FOR stems: LIST OF PATH _ IF module.possibleNameStems # NIL THEN module.possibleNameStems ELSE module.originalPossibleNameStems, stems.rest WHILE stems # NIL DO IF names # NIL THEN names _ Rope.Cat[names, " or"]; names _ Rope.Cat[names, " ", PFS.RopeFromPath[stems.first]]; ENDLOOP; SystemInterface.ShowReport[Rope.Cat["unable to find ", target, " for ", names], $normal]; END; RecoveredVersionStamp: TYPE = RECORD[ mobStamp: MobDefs.VersionStamp, stem: PATH]; <> ConvertDotOFormatVersionStampToMobFormat: PROC[wholeVersionStamp: Rope.ROPE] RETURNS[REF RecoveredVersionStamp] = BEGIN ENABLE BEGIN RuntimeError.BoundsFault => GOTO fails; Convert.Error => GOTO fails; CantConvert => GOTO fails; END; expectedPreamble: Rope.ROPE _ Rope.Cat["@", "(#)", "mob_version ["]; <> stemStart: INT _ Rope.Index[wholeVersionStamp, 0, "] "]+2; stampLength: INT _ Rope.Length[wholeVersionStamp]; preambleLength: INT _ Rope.Length[expectedPreamble]; stemLength: INT _ Rope.Length[wholeVersionStamp]-stemStart; stem: Rope.ROPE _ IF stemLength > 0 THEN Rope.Substr[wholeVersionStamp, stemStart, stemLength] ELSE NIL; preamble: Rope.ROPE _ Rope.Substr[wholeVersionStamp, 0, preambleLength]; digits: Rope.ROPE _ Rope.Substr[wholeVersionStamp, preambleLength, stampLength-preambleLength-stemLength-2]; comma: INT _ Rope.Find[digits, ","]; digits1: Rope.ROPE _ Rope.Substr[digits, 0, comma]; digits2: Rope.ROPE _ Rope.Substr[digits, comma+1, Rope.Length[digits]-comma-1]; stamp: MobDefs.VersionStamp _ [Convert.CardFromRope[digits1], Convert.CardFromRope[digits2]]; IF NOT Rope.Equal[preamble, expectedPreamble] THEN RaiseCantConvert[]; IF stem = NIL THEN RaiseCantConvert[]; RETURN[NEW[RecoveredVersionStamp _ [stamp, PFS.PathFromRope[stem]]]]; EXITS fails => RETURN[NIL]; END; CantConvert: ERROR = CODE; <> RaiseCantConvert: PROC = {CantConvert[]}; DescribeRefStamp: PROC [rs: REF MobDefs.VersionStamp] RETURNS [Rope.ROPE] ~ {IF rs=NIL THEN RETURN ["NIL"] ELSE RETURN IO.PutFR["%08x%08x", [cardinal[rs[0]]], [cardinal[rs[1]]] ]}; <<>> <> <<>> TestGenMesaSourcePositionMacros: Commander.CommandProc = BEGIN args: CommandTool.ArgumentVector _ CommandTool.Parse[cmd]; fileName: PATH _ PFS.PathFromRope[args[1]]; fileSet: SystemInterface.FileSet _ SystemInterface.CreateFileSet[]; BEGIN ENABLE UNWIND => SystemInterface.CloseFileSet[fileSet]; file: CirioFile _ SystemInterface.GetCirioFile[fileSet, fileName]; versionStamp: Rope.ROPE _ NIL; SeeOnePosition: PROC[sp: CARD, nChars: CARD, ln: CARD] = {IO.PutF[cmd.out, "sp: %g..%g, ln: %g\N", IO.card[sp], IO.card[sp+nChars], IO.card[ln]]}; versionStamp _ GenMesaSourcePositionMacros[file, SeeOnePosition]; IO.PutF[cmd.out, "\NversionStamp = %g\N", IO.rope[versionStamp]]; END; SystemInterface.CloseFileSet[fileSet]; END; TestCreateCFileInfo: Commander.CommandProc = BEGIN args: CommandTool.ArgumentVector _ CommandTool.Parse[cmd]; fileName: PATH _ PFS.PathFromRope[args[1]]; fileSet: SystemInterface.FileSet _ SystemInterface.CreateFileSet[]; BEGIN ENABLE UNWIND => SystemInterface.CloseFileSet[fileSet]; file: SystemInterface.CirioFile _ SystemInterface.GetCirioFile[fileSet, fileName]; info: CFileInfo _ CreateCFileInfo[file]; ss: SourcePosSeq _ info.sourcePosSeq; lns: LineNumSeq _ info.lineNumSeq; IO.PutF[cmd.out, "versionStamp: %g\N", IO.rope[info.versionStamp]]; IO.PutF[cmd.out, "nSourcePosMacros = %g\n", IO.card[ss.nSourceMacros]]; FOR I: CARD IN [0..ss.nSourceMacros) DO IO.PutF[cmd.out, "\T%g..%g CLine: %g\N", IO.card[ss[I].pos], IO.card[ss[I].pos+ss[I].nChars], IO.card[ss[I].lineNum]]; ENDLOOP; IO.PutF[cmd.out, "\N"]; FOR I: CARD IN [0..lns.nSourceMacros) DO IO.PutF[cmd.out, "\T CLine: %g %g..%g\N", IO.card[lns[I].lineNum], IO.card[lns[I].pos], IO.card[lns[I].pos+lns[I].nChars]]; ENDLOOP; END; SystemInterface.CloseFileSet[fileSet]; END; <> <> <> TestSetBreak: Commander.CommandProc = BEGIN args: CommandTool.ArgumentVector _ CommandTool.Parse[cmd]; cFileName: PATH _ PFS.PathFromRope[args[1]]; fileSet: SystemInterface.FileSet _ SystemInterface.CreateFileSet[]; BEGIN ENABLE UNWIND => SystemInterface.CloseFileSet[fileSet]; file: SystemInterface.CirioFile _ SystemInterface.GetCirioFile[fileSet, cFileName]; info: CFileInfo _ CreateCFileInfo[file]; pos: SourceFileOpsExtras.Position _ SourceFileOpsExtras.noPosition; cLineNum: CARD; newMesaCharIdx: CARD; IO.PutF[cmd.out, "versionStamp: %g\N", IO.rope[info.versionStamp]]; pos _ SourceFileOpsExtras.FullGetSelection[primary].pos; IO.PutF[cmd.out, "%g in %g selected\N", IO.card[pos.index[char].first], IO.rope[PFS.RopeFromPath[pos.fileName]]]; cLineNum _ LookupMesaSourcePos[info, pos.index[char].first]; IO.PutF[cmd.out, "pointing to line %g in %g\N", IO.card[cLineNum], IO.rope[PFS.RopeFromPath[cFileName]]]; newMesaCharIdx _ LookupCLineNum[info, cLineNum]; IO.PutF[cmd.out, "pointing back to pos %g in %g\N", IO.card[newMesaCharIdx], IO.rope[PFS.RopeFromPath[pos.fileName]]]; SourceFileOpsExtras.FullOpenSource[desc: "Break set at ", pos: [fileName: pos.fileName, uniqueID: SourceFileOpsExtras.nullUniqueID, index: [char: [newMesaCharIdx] ] ], feedBack: cmd.out]; IO.PutF[cmd.out, "\N"]; END; SystemInterface.CloseFileSet[fileSet]; END; TestFromMesa: Commander.CommandProc = BEGIN args: CommandTool.ArgumentVector _ CommandTool.Parse[cmd]; mesaName: PATH _ PFS.PathFromRope[args[1]]; fileSet: SystemInterface.FileSet _ SystemInterface.CreateFileSet[]; BEGIN ENABLE BEGIN UNWIND => SystemInterface.CloseFileSet[fileSet]; SystemInterface.ShowReport => {ShowReportByLevel[cmd.out, msgText, priority]; <> RESUME}; END; modules: CedarModuleSet _ CreateCedarModuleSet[fileSet]; mesaFile: CirioFile _ SystemInterface.GetCirioFile[fileSet, mesaName]; module: CedarModule _ CreateCedarModuleFromMesa[modules, mesaFile]; [] _ GetParsed[module]; [] _ GetCFileInfo[module]; [] _ GetMesaFile[module]; [] _ GetJMPI[module]; [] _ GetMob[module]; [] _ GetModule[module]; END; SystemInterface.CloseFileSet[fileSet]; END; TestFromDotO: Commander.CommandProc = BEGIN args: CommandTool.ArgumentVector _ CommandTool.Parse[cmd]; wholeName: PATH _ PFS.PathFromRope[args[1]]; pc: CARD _ Convert.CardFromRope[args[2]]; fileSet: SystemInterface.FileSet _ SystemInterface.CreateFileSet[]; BEGIN ENABLE BEGIN UNWIND => SystemInterface.CloseFileSet[fileSet]; SystemInterface.ShowReport => {ShowReportByLevel[cmd.out, msgText, priority]; <> RESUME}; END; modules: CedarModuleSet _ CreateCedarModuleSet[fileSet]; wholeFile: CirioFile _ SystemInterface.GetCirioFile[fileSet, wholeName]; whole: ObjF.Parsed _ ObjF.CreateParsed[wholeFile]; embeddedModule: ObjF.Module _ FallBackFindModule[whole, pc]; module: CedarModule _ CreateCedarModuleFromModule[modules, whole, embeddedModule, LIST[wholeName]]; sourcePos: REF CedarSourcePosition _ ComputeCedarSourcePosition[module, [[0, ""], pc]]; IF module # NIL THEN { [] _ GetMesaFile[module]; [] _ GetCFileInfo[module]; [] _ GetMesaFile[module]; [] _ GetJMPI[module]; [] _ GetMob[module]; [] _ GetModule[module]; }; ShowIndentedRopes[GetRopesForSourcePosInfo[sourcePos], cmd.out, 5]; END; SystemInterface.CloseFileSet[fileSet]; END; ShowIndentedRopes: PROC[ropes: LIST OF Rope.ROPE, on: IO.STREAM, indent: CARD] = BEGIN FOR rps: LIST OF Rope.ROPE _ ropes, rps.rest WHILE rps # NIL DO FOR I: CARD IN [0..indent] DO IO.PutF[on, " "]; ENDLOOP; IO.PutF[on, "%g\N", IO.rope[rps.first]]; ENDLOOP; END; CrudeExp: Commander.CommandProc = BEGIN args: CommandTool.ArgumentVector _ CommandTool.Parse[cmd]; mesaName: PATH _ PFS.PathFromRope[args[1]]; mobName: PATH _ PFS.PathFromRope[args[2]]; fileSet: SystemInterface.FileSet _ SystemInterface.CreateFileSet[]; BEGIN ENABLE BEGIN UNWIND => SystemInterface.CloseFileSet[fileSet]; SystemInterface.ShowReport => {ShowReportByLevel[cmd.out, msgText, priority]; <> RESUME}; END; mesaFile: CirioFile _ SystemInterface.GetCirioFile[fileSet, mesaName]; mobFile: CirioFile _ SystemInterface.GetCirioFile[fileSet, mobName]; mob: MA.MobCookie _ MA.CreateMobCookie[mobFile]; mobVersion: MobDefs.VersionStamp _ MA.ReadMobVersionStamp[mob]; mobSourceVersion: MobDefs.VersionStamp _ MA.ReadSourceVersionStamp[mob]; possibleSourceVersion: MobDefs.VersionStamp _ MA.ComputeSourceVersionStamp[mesaFile]; ERROR -- for inspection END; <> END; <> <> NewTestSetBreak: Commander.CommandProc = BEGIN args: CommandTool.ArgumentVector _ CommandTool.Parse[cmd]; remoteName: Rope.ROPE _ args[1]; portNum: CARD _ Convert.CardFromRope[args[2]]; nub: CirioNubAccess.Handle _ CirioNubAccess.CreateRemoteNub[debuggee: remoteName, port: portNum, timeoutMsec: 10000]; fileSet: SystemInterface.FileSet _ SystemInterface.CreateFileSet[]; BEGIN ENABLE BEGIN UNWIND => {SystemInterface.CloseFileSet[fileSet]; CirioNubAccess.DestroyNub[nub]}; SystemInterface.ShowReport => {ShowReportByLevel[cmd.out, msgText, priority]; <> RESUME}; END; modules: CedarModuleSet _ CreateCedarModuleSet[fileSet]; loadState: LoadStateAccess.LoadStateHandle _ LoadStateAccess.CreateLoadStateHandle[remoteName, nub, fileSet]; pos: SourceFileOpsExtras.Position; pos _ SourceFileOpsExtras.FullGetSelection[].pos; IF pos.fileName # NIL THEN BEGIN mesaFileName: PATH ~ pos.fileName; mesaSourcePosition: INT ~ pos.index[char].first; mesaFile: CirioFile _ SystemInterface.GetCirioFile[fileSet, mesaFileName]; addr: REF CedarBreakAddress _ GetAbsAddressForBreak[modules, mesaFile, loadState, mesaSourcePosition]; ropes: LIST OF Rope.ROPE _ GetRopesForCedarBreakAddress[addr]; ShowIndentedRopes[ropes, cmd.out, 0]; IF addr # NIL THEN BEGIN basicInfo: REF LoadStateAccess.BasicPCInfo _ LoadStateAccess.GetBasicPCInfo[loadState, addr.absPC]; moreInfo: REF LoadStateAccess.LoadedModuleInfo _ LoadStateAccess.GetLoadedModuleInfoFromAbsPC[loadState, addr.absPC]; rope1: Rope.ROPE _ LoadStateAccess.GetRopeForBasicPCInfo[basicInfo, addr.absPC, TRUE, TRUE, TRUE, TRUE]; ropes2: LIST OF Rope.ROPE _ LoadStateAccess.GetRopeListForBasicPCInfo[basicInfo]; ropes3: LIST OF Rope.ROPE _ LoadStateAccess.GetRopeListForLoadedModuleInfo[moreInfo]; ShowIndentedRopes[LIST[rope1], cmd.out, 0]; ShowIndentedRopes[ropes2, cmd.out, 0]; ShowIndentedRopes[ropes3, cmd.out, 0]; BEGIN mesaParts: NameParts _ GetNamePartsFromFullPathName[mesaFileName]; ResetSearchPaths[modules, LIST[mesaParts.principalDirectory], BasicTime.Now[]]; <> BEGIN resultingModule: CedarModule _ GetCedarModuleForLoadedModule[modules, moreInfo]; moduleRelativeAddr: CARD _ addr.absPC-(moreInfo.lsi[text].base+moreInfo.moduleRelativeBaseAddr); resultingSourcePos: REF CedarSourcePosition _ ComputeCedarSourcePosition[resultingModule, [[0, ""], moduleRelativeAddr]]; ropes4: LIST OF Rope.ROPE _ GetRopesForSourcePosInfo[resultingSourcePos]; ShowIndentedRopes[ropes4, cmd.out, 0]; IF resultingSourcePos.mesaPosition # addr.correspondingMesaPosition THEN ERROR; END; END; END; END; END; CirioNubAccess.DestroyNub[nub]; SystemInterface.CloseFileSet[fileSet]; END; SetDebugSearch: Commander.CommandProc ~ { debugSearch _ cmd.procData.clientData = $True; msg _ IO.PutFR["debugSearch=%g", [boolean[debugSearch]] ]}; ShowReportByLevel: PUBLIC PROC [s: IO.STREAM, r: Rope.ROPE, level: ATOM] ~ { SELECT messagesDesired FROM $debug => IO.PutF[s, "%g\N", IO.rope[r]]; $normal => SELECT level FROM $debug => {}; $normal, $urgent => IO.PutF[s, "%g\N", IO.rope[r]]; ENDCASE => IO.PutF[s, "Bad level for message: %g\N", IO.rope[r]]; $urgent => SELECT level FROM $debug => {}; $normal => {}; $urgent => IO.PutF[s, "%g\N", IO.rope[r]]; ENDCASE => IO.PutF[s, "Bad level for message: %g\N", IO.rope[r]]; ENDCASE => IO.PutF[s, "Bad desired level for message: %g\N", IO.rope[r]]; }; LevelFromRope: PROC [r: Rope.ROPE] RETURNS [ATOM] ~ { SELECT TRUE FROM Rope.Equal[r, "normal", FALSE] => RETURN[$normal]; Rope.Equal[r, "debug", FALSE] => RETURN[$debug]; Rope.Equal[r, "urgent", FALSE] => RETURN[$urgent]; ENDCASE => RETURN[$error]; }; RopeFromLevel: PROC [l: ATOM] RETURNS [Rope.ROPE _ "ERROR"] ~ { SELECT l FROM $normal => RETURN["normal"]; $debug => RETURN["debug"]; $urgent => RETURN["urgent"]; ENDCASE => RETURN["ERROR"]; }; MessageLevel: PROC [] RETURNS [ATOM _ $error] ~ { levelRope: Rope.ROPE _ UserProfile.Token[key: "Cirio.MessageLevel", default: "normal"]; level: ATOM _ LevelFromRope[levelRope]; IF level = $error THEN level _ $normal; RETURN [level]; }; ChangeLevel: Commander.CommandProc ~ { numArgs:CARD _ CommanderOps.NumArgs[cmd]; newLevel: ATOM _ NIL; newLevelRope: Rope.ROPE _ NIL; IF numArgs > 1 THEN { newLevelRope _ CommanderOps.NextArgument[cmd]; newLevel _ LevelFromRope[newLevelRope]; SELECT newLevel FROM $error => IO.PutF[cmd.out, "level %g is not a valid message level\nValid levels are normal, urgent, and debug.\n", IO.rope[newLevelRope]]; messagesDesired => IO.PutF[cmd.out, "level %g was already the message level.\n", IO.rope[newLevelRope]]; ENDCASE => { IO.PutF[cmd.out, "level changed from %g to %g.\n", IO.rope[RopeFromLevel[messagesDesired]], IO.rope[newLevelRope]]; messagesDesired _ newLevel; } } ELSE IO.PutF[cmd.out, "Current level: %g\n", IO.rope[RopeFromLevel[messagesDesired]]]; }; <
> messagesDesired: ATOM _ MessageLevel[]; debugSearch: BOOL _ FALSE; Commander.Register["ChangeCirioMessageLevel", ChangeLevel, "Change the verbosity level of the messages that Cirio prints out.\n\tUsage: ChangeCirioMessageLevel [level]\n\tValid levels:\n\t\turgent:\tMessages that should always be seen.\n\t\tnormal:\tInformative messages.\n\t\tdebug:\tMore informatation than you want to see.\n\t\tPrint the current setting.\n"]; Commander.Register["TestGenMesaSourcePositionMacros", TestGenMesaSourcePositionMacros]; Commander.Register["TestCreateCFileInfo", TestCreateCFileInfo]; Commander.Register["TestSetBreak", TestSetBreak]; Commander.Register["TestFromMesa", TestFromMesa]; <> <<>> Commander.Register["TestFromDotO", TestFromDotO, "file.o file-rel-pc"]; <> <<>> Commander.Register["CrudeExp", CrudeExp]; <> <<>> Commander.Register["NewTestSetBreak", NewTestSetBreak]; <> <> <> <<[palain-ux]sturgis>Cedar>2.0>System>PlumberImpl.mesa>> Commander.Register["Cirio.DebugSearch", SetDebugSearch, "RMTWModules.debugSearch _ TRUE", $True]; Commander.Register["Cirio.DontDebugSearch", SetDebugSearch, "RMTWModules.debugSearch _ FALSE", $False]; END.