<<>> <> <> <> <> <> <> <> <> <<>> DIRECTORY CCTypes USING[CCError, CCErrorCase, CreateCedarCompilerContext], CirioNubAccess USING[Handle], CirioTypes USING[CompilerContext, Node], FS USING[ComponentPositions, ExpandName], LoadStateAccess USING [LoadStateHandle], ObjectFiles USING[BracketNest, Module, GetBracketNestForPC], RCTW USING [CC, FrameNodeInfo, MakeSimpleFrame, Node, ProcedureFrameInfo, RCTWData, RCTWDataBody], RefTab USING[Create, Ref], Rope USING[Cat, Concat, Equal, Fetch, Find, FindBackward, Length, ROPE, Substr], RuntimeError USING[BoundsFault], SymTab USING[Create]; <> <> <> RCTWModules: CEDAR PROGRAM IMPORTS CCTypes, ObjectFiles, FS, RCTW, RefTab, Rope, RuntimeError, SymTab EXPORTS RCTW = BEGIN OPEN ObjF:ObjectFiles, LSA:LoadStateAccess, RCTW; CCError: ERROR[case: CCTypes.CCErrorCase, msg: Rope.ROPE _ NIL] _ CCTypes.CCError; GetFrameNodeInfo: PUBLIC PROC [serverName: Rope.ROPE, frameInfo: RCTW.ProcedureFrameInfo, handle: CirioNubAccess.Handle, lsh: LSA.LoadStateHandle, module: ObjectFiles.Module] RETURNS [rfni: REF RCTW.FrameNodeInfo] ~ { node: Node; cc: CC; [cc, node] _ GetCCAndFrameFromDotO[serverName, frameInfo, handle, lsh, module]; rfni _ NEW [RCTW.FrameNodeInfo _ [node, cc, GetCFrameDiagnosticInfo, frameInfo]]; RETURN}; GetCFrameDiagnosticInfo: PROC [frame: REF RCTW.FrameNodeInfo] RETURNS[LIST OF Rope.ROPE] ~ { RETURN[LIST["a C frame"]]}; GetCCAndFrameFromDotO: PUBLIC PROC [serverName: Rope.ROPE, frameInfo: RCTW.ProcedureFrameInfo, handle: CirioNubAccess.Handle, lsh: LSA.LoadStateHandle, module: ObjF.Module] RETURNS [CC, Node] ~ { cc: CC _ CCTypes.CreateCedarCompilerContext[]; bracketNest:ObjF.BracketNest _ ObjF.GetBracketNestForPC[module, [[0, ""], frameInfo.relativePC]]; rctw: RCTW.RCTWData _ CreateRCTW[cc, serverName, handle, lsh, module, bracketNest]; frame:Node _ RCTW.MakeSimpleFrame[frameInfo, rctw]; cc.nameScope _ frame; RETURN[cc, frame]}; <> CreateRCTW: PUBLIC PROC[cc: CC, serverName: Rope.ROPE, cirioNub: CirioNubAccess.Handle, lsh: LSA.LoadStateHandle, module: ObjF.Module, bracketNest: ObjF.BracketNest] RETURNS[RCTW.RCTWData] = BEGIN rctw: RCTW.RCTWData _ NEW[RCTW.RCTWDataBody_[ module: module, bracketNest: bracketNest, bracketHashTable: RefTab.Create[], typeRefHashTable: SymTab.Create[], serverName: serverName, lsh: lsh, nub: cirioNub, cc: cc]]; RETURN[rctw]; END; FactoredDotOName: TYPE = RECORD[ name1: Rope.ROPE, remainingPath: Rope.ROPE, stem: Rope.ROPE, cToC: Rope.ROPE, -- either empty or ".ctoc" extension: Rope.ROPE, -- ".o" or empty version: Rope.ROPE -- either empty or ".~" versionNumber "~" or "!" versionNumber ]; FactorDotOName: PROC[dotOLongName: Rope.ROPE] RETURNS[FactoredDotOName] = BEGIN ENABLE RuntimeError.BoundsFault => GOTO fails; FindStartOfVersion: PROC RETURNS[INT] = BEGIN IF length = 0 THEN RETURN[length-1]; IF Rope.Fetch[dotOLongName, length-1] = '~ THEN RETURN[Rope.FindBackward[dotOLongName, ".~", length-2]] ELSE BEGIN lastBang: INT _ Rope.FindBackward[dotOLongName, "!", length-1]; IF lastBang > 0 THEN RETURN[lastBang] ELSE RETURN[length]; END; END; length: INT _ Rope.Length[dotOLongName]; firstSlash: INT _ Rope.Find[dotOLongName, "/"]; secondSlash: INT _ Rope.Find[dotOLongName, "/", firstSlash+1]; lastSlash: INT _ Rope.FindBackward[dotOLongName, "/", length]; startOfVersion: INT _ FindStartOfVersion[]; lastDot: INT _ Rope.FindBackward[dotOLongName, ".", startOfVersion-1]; startOfExtension: INT _ IF Rope.Equal[Rope.Substr[dotOLongName, lastDot+1, startOfVersion-lastDot-1], "o", FALSE] THEN lastDot ELSE startOfVersion; secondLastDot: INT _ Rope.FindBackward[dotOLongName, ".", startOfExtension-1]; startOfcToC: INT _ IF Rope.Equal[Rope.Substr[dotOLongName, secondLastDot+1, startOfExtension-secondLastDot-1], "ctoc", FALSE] THEN secondLastDot ELSE startOfExtension; IF NOT ( firstSlash = 0) AND (firstSlash < secondSlash) AND (secondSlash <= lastSlash) AND (lastSlash < startOfcToC) AND (startOfcToC <= startOfExtension) AND (startOfExtension <= startOfVersion) AND startOfVersion < length THEN BadDotONameSyntax[]; RETURN[[ Rope.Substr[dotOLongName, firstSlash+1, secondSlash-firstSlash-1], Rope.Substr[dotOLongName, secondSlash+1, lastSlash-secondSlash-1], Rope.Substr[dotOLongName, lastSlash+1, startOfcToC-lastSlash-1], Rope.Substr[dotOLongName, startOfcToC, startOfExtension-startOfcToC], Rope.Substr[dotOLongName, startOfExtension, startOfVersion-startOfExtension], Rope.Substr[dotOLongName, startOfVersion, length-startOfVersion]]]; EXITS fails => BadDotONameSyntax[]; END; BadDotONameSyntax: ERROR = CODE; FilePair: TYPE = RECORD[dotO, mob: Rope.ROPE]; FindFiles: PROC[dotOName: Rope.ROPE] RETURNS[FilePair] = BEGIN components: FS.ComponentPositions; fullFName: Rope.ROPE; dirOmitted: BOOL; shortRoot: Rope.ROPE; firstExt: Rope.ROPE; fullFName2: Rope.ROPE; components2: FS.ComponentPositions; dirOmitted2: BOOL; <<>> [fullFName, components, dirOmitted] _ FS.ExpandName[dotOName]; shortRoot _ Rope.Substr[fullFName, components.base.start, components.base.length]; <<>> <> <<>> firstExt _ Rope.Substr[fullFName, components.ext.start, components.ext.length]; IF Rope.Length[firstExt] # 0 AND Rope.Fetch[firstExt, 0] = '~ THEN BEGIN [fullFName2, components2, dirOmitted2] _ FS.ExpandName[shortRoot]; shortRoot _ Rope.Substr[fullFName2, components2.base.start, components2.base.length]; END; <<>> RETURN[[Rope.Cat[shortRoot, ".o"], Rope.Concat[shortRoot, ".mob"]]]; END; END.