<<>> <> <> <> <> <> <> <> <> <> <> <<>> DIRECTORY Atom, BasicTime USING[FromNSTime, GMT, nullGMT, OutOfRange, ToNSTime], CCTypes USING[CCError, CCErrorCase], CirioDeltaFace USING[DebuggeeNameToDebuggerName, TargetVersionMapName], Commander, Convert, MobDefs, MorePfsNames, IO, PFS, PFSNames, Rope, RopeParts, RopeSequence, SimpleFeedback USING[PutFL], SourceFileOps USING [OpenSource, Position], SymTab, SystemInterface USING[CirioFileInfo], VersionMap, VersionMap2, VersionMap2Binding; SystemInterfaceImpl: CEDAR MONITOR LOCKS set USING set: FileSet IMPORTS Atom, BasicTime, CCTypes, CirioDeltaFace, Commander, Convert, IO, MorePfsNames, PFS, PFSNames, Rope, RopeParts, RopeSequence, SimpleFeedback, SourceFileOps, SymTab, VersionMap2, VersionMap2Binding EXPORTS SystemInterface = BEGIN OPEN IO, MPN:MorePfsNames, Rope, RP:RopeParts, RS:RopeSequence, VM2:VersionMap2, VM2Binding:VersionMap2Binding; CCE: ERROR[case: CCTypes.CCErrorCase, msg: Rope.ROPE ¬ NIL] ¬ CCTypes.CCError; <> PATH: TYPE ~ PFSNames.PATH; PathList: TYPE ~ LIST OF PATH; Component: TYPE ~ PFSNames.Component; ROPE: TYPE ~ Rope.ROPE; RopeList: TYPE ~ LIST OF ROPE; RopePart: TYPE ~ RP.RopePart; RopeSeq: TYPE ~ RS.RopeSeq; <<>> <> ShowReport: PUBLIC SIGNAL[msgText: ROPE, priority: ATOM] = CODE; <> << $urgent, $normal, $debug>> <> ShowSource: PUBLIC PROC [desc: ROPE, pos: SourceFileOps.Position, feedBack: STREAM ¬ NIL] = BEGIN SourceFileOps.OpenSource[desc, pos, feedBack]; END; <> <> <<>> <sub-dir>...>rootName.>> <<>> DirectorySeparatorChar: CHAR = '>; DirectorySeparatorString: ROPE = ">"; <<>> <<>> <> <> <> <> <> <> <> <> <> <> <<>> <<>> <> <<{IO.PutF[reports, "selection not in a mesa file, aborting\N"]; RETURN[NIL]};>> <<>> <> <<(THIS should really be in symbol finding)>> <<(we don't check any version stamps, we should)>> <> <> <> <> <> <> <<>> <> < CONTINUE];>> <> <> <> < CONTINUE]};>> <> <<{IO.PutF[reports, "coresponding c file must be in same directory as selected mesa file, aborting\N"]; RETURN[NIL]};>> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<[fullMesaName, positionsInMesaName, dirOmittedInMesaName] _ FS.ExpandName[mesaFileName];>> <> <> <<>> <> <> <> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <<>> <> <> <> <> <> <<>> <> <<[dirPath, rootName, ext] _ DisassembleUnixFileName[dotOFileName];>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> <> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <'s.>> <> <> <> <> <> <> <> <> <> <> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <<>> <> <> <> <> <> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <<>> <> <> <> < lenFileName THEN RETURN [fileName];>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> FileSet: TYPE = REF FileSetBody; FileSetBody: PUBLIC TYPE = MONITORED RECORD[ files: LIST OF CirioFile, nOpenStreams: CARD, openInactiveStreams: LIST OF REF FileStreamInfo, lastOpenInactiveStream: LIST OF REF FileStreamInfo]; CirioFile: TYPE = REF CirioFileBody; <> CirioFileBody: PUBLIC TYPE = RECORD[ fileSet: FileSet, name: PATH, infoValid: BOOLEAN, info: SystemInterface.CirioFileInfo, streams: LIST OF REF FileStreamInfo]; FileStreamInfo: TYPE = RECORD[ file: CirioFile, active: BOOLEAN, stream: IO.STREAM, openFile: PFS.OpenFile, fileInfo: SystemInterface.CirioFileInfo]; <> <> NominalMaxOpenStreams: CARD ¬ 10; <> CreateFileSet: PUBLIC PROC RETURNS[FileSet] = {RETURN[NEW[FileSetBody¬[ , NIL, 0, NIL, NIL]]]}; CloseFileSet: PUBLIC ENTRY PROC[set: FileSet] = BEGIN ENABLE UNWIND => NULL; FOR fl: LIST OF CirioFile ¬ set.files, fl.rest WHILE fl # NIL DO FOR sl: LIST OF REF FileStreamInfo ¬ fl.first.streams, sl.rest WHILE sl # NIL DO IF sl.first.stream # NIL THEN {IO.Close[sl.first.stream]; sl.first.stream ¬ NIL}; ENDLOOP; ENDLOOP; END; GetCirioFileFromDebuggee: PUBLIC PROC[set: FileSet, name: PATH, debuggee: Rope.ROPE, uniqueID: PFS.UniqueID ¬ PFS.nullUniqueID] RETURNS[cf: CirioFile] ~ { localName: PATH ~ DebuggeeUnixNameToDebuggerCedarName[name, debuggee]; cf ¬ GetCirioFile[set, localName, uniqueID]; IF cf=NIL THEN ShowReport[IO.PutFLR["Local name (%g) for remote name (%g, on %g, created %g) doesn't work", LIST[[rope[PFS.RopeFromPath[localName]]], [rope[PFS.RopeFromPath[name]]], [rope[IF debuggee#NIL THEN debuggee ELSE "self"]], [rope[FmtUniqueID[uniqueID]]]] ], $urgent]; RETURN}; <> GetCirioFile: PUBLIC ENTRY PROC[set: FileSet, name: PATH, uniqueID: PFS.UniqueID ¬ PFS.nullUniqueID] RETURNS[CirioFile] = { ENABLE UNWIND => NULL; RETURN InnerGetCirioFile[set, name, uniqueID]}; InnerGetCirioFile: INTERNAL PROC[set: FileSet, name: PATH, uniqueID: PFS.UniqueID] RETURNS[CirioFile] = { noDate: BOOL ~ uniqueID=PFS.nullUniqueID; FOR fl: LIST OF CirioFile ¬ set.files, fl.rest WHILE fl # NIL DO IF name.Equal[fl.first.name] AND (noDate OR uniqueID=fl.first.info.uniqueID) THEN RETURN[fl.first]; ENDLOOP; <> { fileToOpen: PATH ¬ name; file: CirioFile ¬ NEW[CirioFileBody¬[set, fileToOpen, TRUE, [uniqueID, 0, fileToOpen], NIL]]; [bytes: file.info.bytes, uniqueID: file.info.uniqueID] ¬ PFS.FileInfo[file.name, uniqueID !PFS.Error => { asRope: ROPE ~ PFS.RopeFromPath[file.name]; GOTO DontExist}]; set.files ¬ CONS[file, set.files]; RETURN[file]; EXITS DontExist => RETURN [NIL]; }; }; <<>> <> <> GenCirioFilesForInfo: PUBLIC PROC[set: FileSet, pattern: PATH, for: PROC[SystemInterface.CirioFileInfo] RETURNS[thisIsIt: BOOLEAN]] RETURNS[found: CirioFile] = BEGIN ENABLE UNWIND => NULL; result: CirioFile ¬ NIL; local: PROC [ fullFName, attachedTo: PATH, uniqueID: PFS.UniqueID, bytes: INT, mutability: PFS.Mutability, fileType: PFS.FileType ] RETURNS [continue: BOOL] = <<(a PFS.InfoProc)>> BEGIN stop: BOOLEAN ¬ for[[uniqueID, bytes, fullFName]]; IF stop THEN result ¬ GetCirioFile[set, fullFName, uniqueID]; RETURN[NOT stop]; END; PFS.EnumerateForInfo[pattern, local ! PFS.Error => CONTINUE]; RETURN[result]; END; <<>> warnOnVmPfsErr: BOOL ¬ FALSE; verboseGenVm: BOOL ¬ FALSE; <> <> GenVersionMapFilesForInfo: PUBLIC PROC [set: FileSet, map: ATOM, versionStamp: MobDefs.VersionStamp, stems: PathList, suffixes: RopeList, testName: BOOL, for: PROC[SystemInterface.CirioFileInfo] RETURNS[thisIsIt: BOOLEAN], wantedUniqueID: PFS.UniqueID ¬ PFS.nullUniqueID] RETURNS[found: CirioFile ¬ NIL] = { targetMap: ATOM ~ CirioDeltaFace.TargetVersionMapName[map]; vmap: VM2.Map ~ VM2Binding.GetMap[Atom.GetPName[targetMap]]; noDate: BOOL ¬ wantedUniqueID=PFS.nullUniqueID; GenerateNames: PROC [Test: PROC [ROPE] RETURNS [BOOL]] RETURNS [BOOL] ~ { FOR steml: PathList ¬ stems, steml.rest WHILE steml#NIL DO FOR sufl: RopeList ¬ suffixes, sufl.rest WHILE sufl#NIL DO IF Test[ Rope.Concat[ PFS.RopeFromPath[steml.first], sufl.first] ] THEN RETURN [TRUE]; ENDLOOP; ENDLOOP; RETURN [FALSE]}; TryName: PROC [short: ROPE] RETURNS [BOOL] ~ { triedDirs: SymTab.Ref ~ SymTab.Create[case: TRUE]; TryTuple: PROC [t: VM2.VersionTuple] RETURNS [BOOL] ~ { fullRope: ROPE ~ PFS.RopeFromPath[t.name]; foundStamp: VersionMap.VersionStamp ~ t.stamp; uniqueID: PFS.UniqueID ¬ t.created; full: PFSNames.PATH ¬ t.name; directory, verless: PFSNames.PATH; IF verboseGenVm THEN ShowReport[IO.PutFR1["\tvm: %g\n", [rope[fullRope]] ], $urgent]; directory ¬ full.Directory; verless ¬ full.StripVersionNumber; IF noDate THEN { {bytes: INT; [fullFName: full, bytes: bytes, uniqueID: uniqueID] ¬ PFS.FileInfo[full, wantedUniqueID !PFS.Error => { IF warnOnVmPfsErr THEN ShowReport[IO.PutFR["PFS.FileInfo[%g (from version map)] => PFS.Error[%g, %g]", [rope[fullRope]], [atom[error.code]], [rope[error.explanation]] ], $urgent]; uniqueID ¬ PFS.nullUniqueID; GOTO NotMe}]; IF for[[uniqueID, bytes, full]] THEN found ¬ GetCirioFile[set, full, uniqueID]; EXITS NotMe => found ¬ NIL}; IF found=NIL AND triedDirs.Insert[PFS.RopeFromPath[directory], $T] THEN { highestFull: PATH; highestCreated: PFS.UniqueID; FilteringFor: PROC[cfi: SystemInterface.CirioFileInfo] RETURNS[thisIsIt: BOOLEAN] ~ { IF cfi.uniqueID=highestCreated AND cfi.fullName.Equal[highestFull, FALSE] THEN RETURN [FALSE]; RETURN for[cfi]}; {bytes: INT; [fullFName: highestFull, bytes: bytes, uniqueID: highestCreated] ¬ PFS.FileInfo[verless !PFS.Error => { IF warnOnVmPfsErr THEN ShowReport[IO.PutFR["PFS.FileInfo[%g (from version map)] => PFS.Error[%g, %g]", [rope[PFS.RopeFromPath[verless]]], [atom[error.code]], [rope[error.explanation]] ], $urgent]; GOTO NotHere}]; IF highestCreated#uniqueID AND for[[highestCreated, bytes, highestFull]] THEN found ¬ GetCirioFile[set, highestFull, highestCreated]; EXITS NotHere => short ¬ short}; IF found=NIL THEN found ¬ GenCirioFilesForInfo[set, verless.SetVersionNumber[[PFSNames.VersionKind.all, 0]], FilteringFor]}; } ELSE {bytes: INT; [fullFName: full, bytes: bytes, uniqueID: uniqueID] ¬ PFS.FileInfo[verless, wantedUniqueID !PFS.Error => { IF warnOnVmPfsErr THEN ShowReport[IO.PutFLR["PFS.FileInfo[%g (from version map), %g] => PFS.Error[%g, %g]", LIST[[rope[PFS.RopeFromPath[verless]]], IF wantedUniqueID.egmt.gmt=BasicTime.nullGMT THEN [rope["nullGMT"]] ELSE [time[wantedUniqueID.egmt.gmt]], [atom[error.code]], [rope[error.explanation]]] ], $urgent]; GOTO None}]; IF for[[uniqueID, bytes, full]] THEN found ¬ GetCirioFile[set, full, uniqueID]; EXITS None => NULL}; RETURN [found#NIL]}; pat: VM2.VersionTuple ~ [VM2.ShortNameToPattern[short].name, wantedUniqueID, versionStamp]; RETURN [VM2.ScanMatches[vmap, TryTuple, FALSE, pat].found]}; IF testName THEN [] ¬ GenerateNames[TryName] ELSE [] ¬ TryName["*"]; RETURN}; GetNameOfFile: PUBLIC PROC[file: CirioFile] RETURNS[PATH] = BEGIN inner: ENTRY PROC[set: FileSet] RETURNS[PATH] = {ENABLE UNWIND => NULL; RETURN[file.name]}; IF file = NIL THEN RETURN[NIL] ELSE RETURN[inner[file.fileSet]]; END; GetFileInfo: PUBLIC PROC[file: CirioFile] RETURNS[SystemInterface.CirioFileInfo] = BEGIN inner: ENTRY PROC[set: FileSet] RETURNS[SystemInterface.CirioFileInfo] = BEGIN ENABLE UNWIND => NULL; IF NOT file.infoValid THEN ERROR<>; RETURN[file.info]; END; RETURN[inner[file.fileSet]] END; GetStreamForFile: PUBLIC PROC[file: CirioFile] RETURNS[IO.STREAM] = { IF file=NIL THEN RETURN[NIL] ELSE RETURN EnterGetStreamForFile[file.fileSet, file]}; EnterGetStreamForFile: ENTRY PROC[set: FileSet, file: CirioFile] RETURNS[IO.STREAM] = { ENABLE UNWIND => NULL; RETURN InnerGetStreamForFile[set, file]}; InnerGetStreamForFile: INTERNAL PROC[set: FileSet, file: CirioFile] RETURNS[IO.STREAM] = { IF NOT file.infoValid THEN ERROR<>; FOR sl: LIST OF REF FileStreamInfo ¬ file.streams, sl.rest WHILE sl # NIL DO IF NOT sl.first.active THEN BEGIN sl.first.active ¬ TRUE; IF sl.first.stream # NIL THEN BEGIN -- remove from the open but inactive list, and reset position set: FileSet ¬ file.fileSet; stream: REF FileStreamInfo ¬ sl.first; removed: BOOLEAN ¬ FALSE; info: SystemInterface.CirioFileInfo; IF set.openInactiveStreams = NIL THEN ERROR; IF set.openInactiveStreams.first = stream THEN {set.openInactiveStreams ¬ set.openInactiveStreams.rest; removed ¬ TRUE} ELSE FOR sl: LIST OF REF FileStreamInfo ¬ set.openInactiveStreams, sl.rest WHILE sl.rest # NIL DO IF sl.rest.first = stream THEN {sl.rest ¬ sl.rest.rest; removed ¬ TRUE; EXIT}; ENDLOOP; IF NOT removed THEN ERROR; IF set.lastOpenInactiveStream.first = stream THEN BEGIN -- ugh ... fixup IF set.openInactiveStreams = NIL THEN set.lastOpenInactiveStream ¬ NIL ELSE FOR sl: LIST OF REF FileStreamInfo ¬ set.openInactiveStreams, sl.rest DO IF sl.rest = NIL THEN {set.lastOpenInactiveStream ¬ sl; EXIT}; ENDLOOP; END; <> [bytes: info.bytes, uniqueID: info.uniqueID] ¬ PFS.GetInfo[stream.openFile]; IF info.bytes # stream.fileInfo.bytes OR info.uniqueID # stream.fileInfo.uniqueID THEN -- file has changed ERROR PFS.Error[[environment, $ImmutableFileChanged, IO.PutFR["The CirioFile for %g of %g len %g has changed", [rope[PFS.RopeFromPath[file.name]]], [rope[FmtUniqueID[file.info.uniqueID]]], [integer[file.info.bytes]] ]]] <>; IO.SetIndex[stream.stream, 0]; RETURN[stream.stream]; END ELSE -- we have to open the stream BEGIN sl.first.stream ¬ PFS.StreamOpen[file.name, read, file.info.uniqueID]; sl.first.openFile ¬ PFS.OpenFileFromStream[sl.first.stream]; sl.first.fileInfo ¬ file.info; <<[bytes: sl.first.fileInfo.bytes, uniqueID: sl.first.fileInfo.uniqueID] ¬ PFS.GetInfo[sl.first.openFile]; file.info ¬ sl.first.fileInfo; -- update the file info>> file.fileSet.nOpenStreams ¬ file.fileSet.nOpenStreams+1; CheckNOpenStreamsP[file.fileSet]; RETURN[sl.first.stream]; END; END; ENDLOOP; <> BEGIN stream: IO.STREAM ¬ PFS.StreamOpen[file.name, read, file.info.uniqueID]; openFile: PFS.OpenFile ¬ PFS.OpenFileFromStream[stream]; streamInfo: REF FileStreamInfo ¬ NEW[FileStreamInfo¬[ file, TRUE, stream, openFile, file.info]]; <<[bytes: streamInfo.fileInfo.bytes, uniqueID: streamInfo.fileInfo.uniqueID] ¬ PFS.GetInfo[openFile]; file.info ¬ streamInfo.fileInfo; -- update the file info>> file.streams ¬ CONS[streamInfo, file.streams]; file.fileSet.nOpenStreams ¬ file.fileSet.nOpenStreams+1; CheckNOpenStreamsP[file.fileSet]; RETURN[file.streams.first.stream]; END; }; ReleaseStreamForFile: PUBLIC PROC[file: CirioFile, stream: IO.STREAM] = BEGIN inner: ENTRY PROC[set: FileSet] = BEGIN ENABLE UNWIND => NULL; FOR sl: LIST OF REF FileStreamInfo ¬ file.streams, sl.rest WHILE sl # NIL DO IF sl.first.stream = stream THEN BEGIN cell: LIST OF REF FileStreamInfo ¬ LIST[sl.first]; cell.first.active ¬ FALSE; IF file.fileSet.openInactiveStreams = NIL THEN file.fileSet.openInactiveStreams ¬ cell ELSE file.fileSet.lastOpenInactiveStream.rest ¬ cell; file.fileSet.lastOpenInactiveStream ¬ cell; CheckNOpenStreamsP[file.fileSet]; RETURN; END; ENDLOOP; ERROR; END; inner[file.fileSet]; END; CheckNOpenStreamsP: PROC[set: FileSet] = BEGIN IF set.nOpenStreams > NominalMaxOpenStreams AND set.openInactiveStreams # NIL THEN BEGIN toClose: REF FileStreamInfo ¬ set.openInactiveStreams.first; set.openInactiveStreams ¬ set.openInactiveStreams.rest; IO.Close[toClose.stream]; toClose.stream ¬ NIL; IF toClose.active THEN ERROR; set.nOpenStreams ¬ set.nOpenStreams - 1; END; END; <<>> <> <<>> BadDotONameSyntax: ERROR = CODE; <> <> <> <> <> <> <> <> <> <> < GOTO fails; cirioPrefix: PATH ¬ PFSNames.EmptyPath; cirioRemainingFileName: PATH ¬ PFSNames.EmptyPath; volume: PATH ¬ PFSNames.EmptyPath; name1: PATH ¬ PFSNames.EmptyPath; remainingPath: PATH ¬ PFSNames.EmptyPath; machineDependentSubdir: PATH ¬ PFSNames.EmptyPath; stem: RopePart; secondaryExtension: RopePart; extension: RopePart; version: PFSNames.Version; fileNameSeq: RopeSeq ¬ NIL; tentativeRemainingPath: LIST OF Component ¬ NIL; exit: BOOLEAN ¬ FALSE; <> curPart: Component ¬ unixFileName.Fetch[1]; curPartRope: ROPE ¬ curPart.ComponentRope; nextPart: INT ¬ 1; IF Rope.Equal[curPartRope, "tmp_mnt", FALSE] THEN { curPart ¬ unixFileName.Fetch[2]; curPartRope ¬ curPart.ComponentRope; IF Rope.Equal[curPartRope, "net", FALSE] THEN { nextPart ¬ 3; volume ¬ PFSNames.ConstructName[LIST[unixFileName.Fetch[0], unixFileName.Fetch[1], curPart], FALSE, TRUE]; }; } ELSE IF curPartRope.Equal["volume", FALSE] OR curPartRope.Equal["net", FALSE] OR curPartRope.Equal["pseudo", FALSE] THEN { nextPart ¬ 2; volume ¬ PFSNames.ConstructName[LIST[unixFileName.Fetch[0], curPart], FALSE, TRUE]; }; IF volume = PFSNames.EmptyPath THEN volume ¬ PFSNames.ConstructName[LIST[unixFileName.Fetch[0]], FALSE, TRUE]; IF PFS.RopeFromPath[volume].Substr[0,3].Equal["-ux"] THEN volume ¬ PFS.PathFromRope[PFS.RopeFromPath[volume].Replace[0, 3, ""]]; <> IF unixFileName.ComponentCount # 3 OR volume.ComponentCount = 1 THEN { curPart ¬ unixFileName.Fetch[nextPart]; name1 ¬ PFSNames.ConstructName[LIST[curPart], FALSE, TRUE]} ELSE nextPart ¬ nextPart - 1; <> nextPart ¬ nextPart + 1; FOR part: INT ¬ nextPart, part+1 UNTIL part = unixFileName.ComponentCount-1 OR exit = TRUE DO nextPart ¬ part+1; curPart ¬ unixFileName.Fetch[part]; IF CirioDeltaFace.IsMachineDependentSubdirectory[curPart] THEN { exit ¬ TRUE; machineDependentSubdir ¬ PFSNames.ConstructName[LIST[curPart], FALSE, TRUE]} ELSE tentativeRemainingPath ¬ CONS[curPart, tentativeRemainingPath]; ENDLOOP; remainingPath ¬ PFSNames.ConstructName[tentativeRemainingPath, FALSE, TRUE, TRUE]; <> curPart ¬ unixFileName.Fetch[nextPart]; version ¬ curPart.version; curPartRope ¬ curPart.ComponentRope; { fnPart: RopePart ¬ RS.PartFromRope[curPartRope]; fileNameSeq ¬ RS.ParsePartToSeq[fnPart, '.]; SELECT fileNameSeq.ComponentCount FROM 1 => stem ¬ fileNameSeq.Fetch[0]; 2 => { stem ¬ fileNameSeq.Fetch[0]; extension ¬ fileNameSeq.Fetch[1]; }; 3 => { stem ¬ fileNameSeq.Fetch[0]; secondaryExtension ¬ fileNameSeq.Fetch[1]; extension ¬ fileNameSeq.Fetch[2]; }; ENDCASE => { stem ¬ fileNameSeq.Fetch[0]; secondaryExtension ¬ fileNameSeq.Fetch[1]; extension ¬ fileNameSeq.Fetch[2]; }; }; cirioPrefix ¬ volume.Cat[name1]; cirioRemainingFileName ¬ PFSNames.EmptyPath; cirioRemainingFileName ¬ remainingPath.Cat[machineDependentSubdir]; cirioRemainingFileName ¬ cirioRemainingFileName.Cat[ PFS.PathFromRope[RS.ConstructSeq[LIST[stem,secondaryExtension,extension]].UnparseSeqToPart['.].RopeFromPart]]; <> curPartRope ¬ PFS.RopeFromPath[cirioRemainingFileName]; IF curPartRope.Fetch[curPartRope.Length-1] = ': THEN cirioRemainingFileName ¬ PFS.PathFromRope[curPartRope.Substr[0, curPartRope.Length - 1]]; cirioRemainingFileName ¬ cirioRemainingFileName.SetVersionNumber[version]; RETURN[[ cirioPrefix: cirioPrefix, cirioRemainingFileName: cirioRemainingFileName, volume: volume, name1: name1, remainingPath: remainingPath, machineDependentSubdir: machineDependentSubdir, stem: stem, secondaryExtension: secondaryExtension, extension: extension, version: version ]]; EXITS fails => BadDotONameSyntax[]; END; GetLocalFileName: PROC [fileName: PFSNames.PATH, serverName: ROPE ¬ NIL] RETURNS [PFSNames.PATH] ~ { unixName: FactoredUnixFileName ¬ []; ourPrefix: PATH; <> IF serverName = NIL OR serverName.Equal["sameWorld"] THEN RETURN [fileName]; <> unixName ¬ FactorUnixFileName[fileName ! BadDotONameSyntax => BEGIN ShowReport[Rope.Cat["Unable to factor unix name ", PFS.RopeFromPath[fileName]], $urgent]; unixName.cirioPrefix ¬ NIL; CONTINUE; END;]; IF debugNaming THEN SimpleFeedback.PutF[$CirioSystemInterface, oneLiner, $Naming, "Factor[%g, %g] => %g", [rope[PFS.RopeFromPath[fileName]]], [rope[IF serverName=NIL THEN "NIL" ELSE Convert.RopeFromRope[serverName]]], [rope[FmtFufn[unixName]]] ]; IF unixName.cirioPrefix = NIL THEN RETURN[fileName]; <> ourPrefix ¬ CirioDeltaFace.GetOurPrefixForUnixPrefix[unixName.volume, unixName.name1, serverName, "ux"]; IF debugNaming THEN SimpleFeedback.PutF[$CirioSystemInterface, oneLiner, $Naming, "GetOur... => %g", [rope[PFS.RopeFromPath[ourPrefix]]] ]; RETURN[ourPrefix.Cat[unixName.cirioRemainingFileName]]; }; FmtFufn: PROC [fufn: FactoredUnixFileName] RETURNS [ROPE] ~ { buf: IO.STREAM ~ IO.ROS[]; buf.PutF["[cp:%g, crfn:%g; vol:%g, n1:%g, ", [rope[PFS.RopeFromPath[fufn.cirioPrefix]]], [rope[PFS.RopeFromPath[fufn.cirioRemainingFileName]]], [rope[PFS.RopeFromPath[fufn.volume]]], [rope[PFS.RopeFromPath[fufn.name1]]] ]; buf.PutF["rp:%g, mds:%g, stem:%g, se:%g, e:%g, v:", [rope[PFS.RopeFromPath[fufn.remainingPath]]], [rope[PFS.RopeFromPath[fufn.machineDependentSubdir]]], [rope[RS.RopeFromPart[fufn.stem]]], [rope[RS.RopeFromPart[fufn.secondaryExtension]]], [rope[RS.RopeFromPart[fufn.extension]]] ]; SELECT fufn.version.versionKind FROM numeric => buf.Put[ [cardinal[fufn.version.version]] ]; none => buf.PutRope["none"]; lowest => buf.PutRope["lowest"]; highest => buf.PutRope["highest"]; next => buf.PutRope["next"]; all => buf.PutRope["all"]; ENDCASE => buf.PutRope["?"]; buf.PutChar[']]; RETURN buf.RopeFromROS[]}; >> DebuggeeUnixNameToDebuggerCedarName: PUBLIC PROC [unixName: PATH, debuggee: ROPE] RETURNS [cedar: PATH] ~ { lc: Component; c0: ROPE ¬ "-ux"; cedar ¬ unixName; lc ¬ cedar.ShortName[]; IF NOT cedar.Fetch[0].ComponentRope.IsEmpty THEN ShowReport[IO.PutFR["Given unix name (%g) on debuggee (%g) with non-empty 0'th component", [rope[PFS.RopeFromPath[unixName]]], [rope[debuggee]] ], $normal] ELSE IF lc.version.versionKind # none THEN ShowReport[IO.PutFR["Given unix name (%g) on debuggee (%g) with non-empty version", [rope[PFS.RopeFromPath[unixName]]], [rope[debuggee]] ], $normal] ELSE { rs: RopeSeq ~ RS.ParsePartToSeq[MPN.ComponentName[lc], '.]; n: NAT ~ RS.Length[rs]; le: RopePart ~ rs.Fetch[n-1]; lel: INT ~ le.Length[]; IF lel>2 AND le.Fetch[0]='~ AND le.Fetch[lel-1]='~ THEN { ver: CARD ~ Convert.CardFromRope[le.Substr[start: 1, len: lel-2].ToRope !Convert.Error => GOTO NotNum]; IF ver > CARDINAL.LAST THEN ShowReport[IO.PutFR["Can't naturalize huge version of unix name (%g) from debuggee (%g) - left in -ux: syntax", [rope[PFS.RopeFromPath[unixName]]], [rope[debuggee]] ], $urgent] ELSE { lc.name.len ¬ lc.name.len - (lel+1); lc.version ¬ [numeric, ver]; cedar ¬ cedar.ReplaceShortName[lc]; c0 ¬ "-vux"}; EXITS NotNum => c0 ¬ c0}; cedar ¬ cedar.ReplaceComponent[0, [name: [c0, 0, c0.Length]]]; }; IF debuggee#NIL AND NOT debuggee.Equal["SameWorld", FALSE] THEN { Warn: PROC [r: ROPE] ~ {ShowReport[r, $urgent]}; local: PATH ~ CirioDeltaFace.DebuggeeNameToDebuggerName[cedar, debuggee, Warn]; IF debugNaming THEN SimpleFeedback.PutFL[$SystemInterfaceImpl, oneLiner, $Naming, "Localize[%g, %g] => %g", LIST[[rope[debuggee]], [rope[PFS.RopeFromPath[cedar]]], [rope[PFS.RopeFromPath[local]]]] ]; cedar ¬ local}; RETURN}; debugNaming: BOOL ¬ FALSE; FmtUniqueID: PUBLIC PROC [uid: PFS.UniqueID] RETURNS [ROPE] ~ { time: ROPE ¬ "error formatting time"; IF uid.egmt.gmt = BasicTime.nullGMT THEN time ¬ "unspecified" ELSE time ¬ Convert.RopeFromTime[uid.egmt.gmt, years, seconds, FALSE, FALSE !Convert.Error => CONTINUE]; IF uid.egmt.usecs#0 THEN time ¬ IO.PutFR["%g plus %gus", [rope[time]], [cardinal[uid.egmt.usecs]] ]; IF uid.host # [0, 0] THEN time ¬ IO.PutFR["%g host [%xH, %xH]", [rope[time]], [cardinal[uid.host.a]], [cardinal[uid.host.b]] ]; RETURN [time]}; VersionStampToUniqueID: PUBLIC PROC [vs: MobDefs.VersionStamp] RETURNS [uid: PFS.UniqueID] ~ { IF vs[1]#0 THEN CCE[cirioError, IO.PutFR["MobDefs.VersionStamp[%xH, %xH] can't be converted to a create date", [cardinal[vs[0]]], [cardinal[vs[1]]] ]]; uid.egmt.gmt ¬ BasicTime.FromNSTime[vs[0] ! BasicTime.OutOfRange => CCE[cirioError, IO.PutFR1["MobDefs.VersionStamp[%xH, 0] doesn't encode a valid create date", [cardinal[vs[0]]] ]] ]; RETURN}; UniqueIDToVersionStamp: PUBLIC PROC [uid: PFS.UniqueID] RETURNS [vs: MobDefs.VersionStamp] ~ { IF uid.egmt.usecs # 0 OR uid.host # [0, 0] THEN ERROR CCE[cirioError, IO.PutFR1["PFS.UniqueID %g can't be converted to a MobDefs.VersionStamp", [rope[FmtUniqueID[uid]]] ]]; vs ¬ [BasicTime.ToNSTime[uid.egmt.gmt], 0]; RETURN}; <> Verbosify: Commander.CommandProc = {warnOnVmPfsErr ¬ verboseGenVm ¬ TRUE}; Tersify: Commander.CommandProc = {warnOnVmPfsErr ¬ verboseGenVm ¬ FALSE}; Commander.Register["Cirio.verboseScanVersionMaps", Verbosify]; Commander.Register["Cirio.terseScanVersionMaps", Tersify]; END.